@comergehq/studio 0.1.9 → 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 +1120 -863
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +911 -654
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/chat/ChatComposer.tsx +9 -7
- package/src/components/chat/ChatMessageList.tsx +21 -35
- package/src/components/chat/ChatPage.tsx +3 -1
- package/src/components/comments/AppCommentsSheet.tsx +6 -6
- package/src/components/floating-draggable-button/FloatingDraggableButton.tsx +12 -27
- package/src/components/preview/StatsBar.tsx +4 -3
- package/src/components/studio-sheet/StudioBottomSheet.tsx +3 -3
- package/src/components/studio-sheet/StudioSheetBackground.tsx +3 -2
- package/src/components/studio-sheet/StudioSheetHeaderIconButton.tsx +7 -5
- package/src/components/utils/ResettableLiquidGlassView.tsx +28 -0
- package/src/components/utils/liquidGlassReset.tsx +36 -0
- package/src/studio/ComergeStudio.tsx +51 -15
- package/src/studio/hooks/useAttachmentUpload.ts +51 -5
- package/src/studio/hooks/useBundleManager.ts +91 -17
- package/src/studio/hooks/useOptimisticChatMessages.ts +128 -0
- package/src/studio/ui/ChatPanel.tsx +1 -0
- package/src/studio/ui/RuntimeRenderer.tsx +7 -2
- package/src/studio/ui/StudioOverlay.tsx +11 -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 React42 from "react";
|
|
10
10
|
import { Platform as RNPlatform, View as View45 } from "react-native";
|
|
11
11
|
import { BottomSheetModalProvider } from "@gorhom/bottom-sheet";
|
|
12
12
|
|
|
@@ -952,6 +952,39 @@ var BundlesRepositoryImpl = class extends BaseRepository {
|
|
|
952
952
|
var bundlesRepository = new BundlesRepositoryImpl(bundlesRemoteDataSource);
|
|
953
953
|
|
|
954
954
|
// src/studio/hooks/useBundleManager.ts
|
|
955
|
+
function sleep(ms) {
|
|
956
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
957
|
+
}
|
|
958
|
+
function isRetryableNetworkError(e) {
|
|
959
|
+
var _a;
|
|
960
|
+
const err = e;
|
|
961
|
+
const code = typeof (err == null ? void 0 : err.code) === "string" ? err.code : "";
|
|
962
|
+
const message = typeof (err == null ? void 0 : err.message) === "string" ? err.message : "";
|
|
963
|
+
if (code === "ERR_NETWORK" || code === "ECONNABORTED") return true;
|
|
964
|
+
if (message.toLowerCase().includes("network error")) return true;
|
|
965
|
+
if (message.toLowerCase().includes("timeout")) return true;
|
|
966
|
+
const status = typeof ((_a = err == null ? void 0 : err.response) == null ? void 0 : _a.status) === "number" ? err.response.status : void 0;
|
|
967
|
+
if (status && (status === 429 || status >= 500)) return true;
|
|
968
|
+
return false;
|
|
969
|
+
}
|
|
970
|
+
async function withRetry(fn, opts) {
|
|
971
|
+
let lastErr = null;
|
|
972
|
+
for (let attempt = 1; attempt <= opts.attempts; attempt += 1) {
|
|
973
|
+
try {
|
|
974
|
+
return await fn();
|
|
975
|
+
} catch (e) {
|
|
976
|
+
lastErr = e;
|
|
977
|
+
const retryable = isRetryableNetworkError(e);
|
|
978
|
+
if (!retryable || attempt >= opts.attempts) {
|
|
979
|
+
throw e;
|
|
980
|
+
}
|
|
981
|
+
const exp = Math.min(opts.maxDelayMs, opts.baseDelayMs * Math.pow(2, attempt - 1));
|
|
982
|
+
const jitter = Math.floor(Math.random() * 250);
|
|
983
|
+
await sleep(exp + jitter);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
throw lastErr;
|
|
987
|
+
}
|
|
955
988
|
function safeName(s) {
|
|
956
989
|
return s.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
957
990
|
}
|
|
@@ -1009,8 +1042,16 @@ async function getExistingNonEmptyFileUri(fileUri) {
|
|
|
1009
1042
|
async function downloadIfMissing(url, fileUri) {
|
|
1010
1043
|
const existing = await getExistingNonEmptyFileUri(fileUri);
|
|
1011
1044
|
if (existing) return existing;
|
|
1012
|
-
|
|
1013
|
-
|
|
1045
|
+
return await withRetry(
|
|
1046
|
+
async () => {
|
|
1047
|
+
await deleteFileIfExists(fileUri);
|
|
1048
|
+
const res = await FileSystem.downloadAsync(url, fileUri);
|
|
1049
|
+
const ok = await getExistingNonEmptyFileUri(res.uri);
|
|
1050
|
+
if (!ok) throw new Error("Downloaded bundle is empty.");
|
|
1051
|
+
return res.uri;
|
|
1052
|
+
},
|
|
1053
|
+
{ attempts: 3, baseDelayMs: 500, maxDelayMs: 4e3 }
|
|
1054
|
+
);
|
|
1014
1055
|
}
|
|
1015
1056
|
async function deleteFileIfExists(fileUri) {
|
|
1016
1057
|
try {
|
|
@@ -1024,11 +1065,15 @@ async function deleteFileIfExists(fileUri) {
|
|
|
1024
1065
|
async function safeReplaceFileFromUrl(url, targetUri, tmpKey) {
|
|
1025
1066
|
const tmpUri = toBundleFileUri(`tmp:${tmpKey}:${Date.now()}`);
|
|
1026
1067
|
try {
|
|
1027
|
-
await
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1068
|
+
await withRetry(
|
|
1069
|
+
async () => {
|
|
1070
|
+
await deleteFileIfExists(tmpUri);
|
|
1071
|
+
await FileSystem.downloadAsync(url, tmpUri);
|
|
1072
|
+
const tmpOk = await getExistingNonEmptyFileUri(tmpUri);
|
|
1073
|
+
if (!tmpOk) throw new Error("Downloaded bundle is empty.");
|
|
1074
|
+
},
|
|
1075
|
+
{ attempts: 3, baseDelayMs: 500, maxDelayMs: 4e3 }
|
|
1076
|
+
);
|
|
1032
1077
|
await deleteFileIfExists(targetUri);
|
|
1033
1078
|
await FileSystem.moveAsync({ from: tmpUri, to: targetUri });
|
|
1034
1079
|
const finalOk = await getExistingNonEmptyFileUri(targetUri);
|
|
@@ -1041,28 +1086,44 @@ async function safeReplaceFileFromUrl(url, targetUri, tmpKey) {
|
|
|
1041
1086
|
async function pollBundle(appId, bundleId, opts) {
|
|
1042
1087
|
const start = Date.now();
|
|
1043
1088
|
while (true) {
|
|
1044
|
-
|
|
1045
|
-
|
|
1089
|
+
try {
|
|
1090
|
+
const bundle = await bundlesRepository.getById(appId, bundleId);
|
|
1091
|
+
if (bundle.status === "succeeded" || bundle.status === "failed") return bundle;
|
|
1092
|
+
} catch (e) {
|
|
1093
|
+
if (!isRetryableNetworkError(e)) {
|
|
1094
|
+
throw e;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1046
1097
|
if (Date.now() - start > opts.timeoutMs) {
|
|
1047
1098
|
throw new Error("Bundle build timed out.");
|
|
1048
1099
|
}
|
|
1049
|
-
await
|
|
1100
|
+
await sleep(opts.intervalMs);
|
|
1050
1101
|
}
|
|
1051
1102
|
}
|
|
1052
1103
|
async function resolveBundlePath(src, platform, mode) {
|
|
1053
1104
|
const { appId, commitId } = src;
|
|
1054
1105
|
const dir = bundlesCacheDir();
|
|
1055
1106
|
await ensureDir(dir);
|
|
1056
|
-
const initiate = await
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1107
|
+
const initiate = await withRetry(
|
|
1108
|
+
async () => {
|
|
1109
|
+
return await bundlesRepository.initiate(appId, {
|
|
1110
|
+
platform,
|
|
1111
|
+
commitId: commitId ?? void 0,
|
|
1112
|
+
idempotencyKey: `${appId}:${commitId ?? "head"}:${platform}`
|
|
1113
|
+
});
|
|
1114
|
+
},
|
|
1115
|
+
{ attempts: 3, baseDelayMs: 500, maxDelayMs: 4e3 }
|
|
1116
|
+
);
|
|
1061
1117
|
const finalBundle = initiate.status === "succeeded" || initiate.status === "failed" ? initiate : await pollBundle(appId, initiate.id, { timeoutMs: 3 * 60 * 1e3, intervalMs: 1200 });
|
|
1062
1118
|
if (finalBundle.status === "failed") {
|
|
1063
1119
|
throw new Error("Bundle build failed.");
|
|
1064
1120
|
}
|
|
1065
|
-
const signed = await
|
|
1121
|
+
const signed = await withRetry(
|
|
1122
|
+
async () => {
|
|
1123
|
+
return await bundlesRepository.getSignedDownloadUrl(appId, finalBundle.id, { redirect: false });
|
|
1124
|
+
},
|
|
1125
|
+
{ attempts: 3, baseDelayMs: 500, maxDelayMs: 4e3 }
|
|
1126
|
+
);
|
|
1066
1127
|
const bundlePath = mode === "base" ? await safeReplaceFileFromUrl(
|
|
1067
1128
|
signed.url,
|
|
1068
1129
|
toBundleFileUri(baseBundleKey(appId, platform)),
|
|
@@ -1078,6 +1139,7 @@ function useBundleManager({
|
|
|
1078
1139
|
const [bundlePath, setBundlePath] = React5.useState(null);
|
|
1079
1140
|
const [renderToken, setRenderToken] = React5.useState(0);
|
|
1080
1141
|
const [loading, setLoading] = React5.useState(false);
|
|
1142
|
+
const [loadingMode, setLoadingMode] = React5.useState(null);
|
|
1081
1143
|
const [statusLabel, setStatusLabel] = React5.useState(null);
|
|
1082
1144
|
const [error, setError] = React5.useState(null);
|
|
1083
1145
|
const [isTesting, setIsTesting] = React5.useState(false);
|
|
@@ -1093,6 +1155,7 @@ function useBundleManager({
|
|
|
1093
1155
|
baseOpIdRef.current += 1;
|
|
1094
1156
|
if (activeLoadModeRef.current === "base") {
|
|
1095
1157
|
setLoading(false);
|
|
1158
|
+
setLoadingMode(null);
|
|
1096
1159
|
setStatusLabel(null);
|
|
1097
1160
|
activeLoadModeRef.current = null;
|
|
1098
1161
|
}
|
|
@@ -1157,6 +1220,7 @@ function useBundleManager({
|
|
|
1157
1220
|
const opId = mode === "base" ? ++baseOpIdRef.current : ++testOpIdRef.current;
|
|
1158
1221
|
activeLoadModeRef.current = mode;
|
|
1159
1222
|
setLoading(true);
|
|
1223
|
+
setLoadingMode(mode);
|
|
1160
1224
|
setError(null);
|
|
1161
1225
|
setStatusLabel(mode === "test" ? "Loading test bundle\u2026" : "Loading latest build\u2026");
|
|
1162
1226
|
if (mode === "base") {
|
|
@@ -1199,6 +1263,7 @@ function useBundleManager({
|
|
|
1199
1263
|
if (mode === "base" && opId !== baseOpIdRef.current) return;
|
|
1200
1264
|
if (mode === "test" && opId !== testOpIdRef.current) return;
|
|
1201
1265
|
setLoading(false);
|
|
1266
|
+
setLoadingMode(null);
|
|
1202
1267
|
if (activeLoadModeRef.current === mode) activeLoadModeRef.current = null;
|
|
1203
1268
|
}
|
|
1204
1269
|
}, [activateCachedBase, platform]);
|
|
@@ -1220,7 +1285,7 @@ function useBundleManager({
|
|
|
1220
1285
|
if (!canRequestLatest) return;
|
|
1221
1286
|
void loadBase();
|
|
1222
1287
|
}, [base.appId, base.commitId, platform, canRequestLatest, loadBase]);
|
|
1223
|
-
return { bundlePath, renderToken, loading, statusLabel, error, isTesting, loadBase, loadTest, restoreBase };
|
|
1288
|
+
return { bundlePath, renderToken, loading, loadingMode, statusLabel, error, isTesting, loadBase, loadTest, restoreBase };
|
|
1224
1289
|
}
|
|
1225
1290
|
|
|
1226
1291
|
// src/studio/hooks/useMergeRequests.ts
|
|
@@ -1479,6 +1544,8 @@ function useMergeRequests(params) {
|
|
|
1479
1544
|
|
|
1480
1545
|
// src/studio/hooks/useAttachmentUpload.ts
|
|
1481
1546
|
import * as React7 from "react";
|
|
1547
|
+
import { Platform } from "react-native";
|
|
1548
|
+
import * as FileSystem2 from "expo-file-system/legacy";
|
|
1482
1549
|
|
|
1483
1550
|
// src/data/attachment/remote.ts
|
|
1484
1551
|
var AttachmentRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -1518,6 +1585,40 @@ var attachmentRepository = new AttachmentRepositoryImpl(
|
|
|
1518
1585
|
);
|
|
1519
1586
|
|
|
1520
1587
|
// src/studio/hooks/useAttachmentUpload.ts
|
|
1588
|
+
async function dataUrlToBlobAndroid(dataUrl) {
|
|
1589
|
+
const normalized = dataUrl.startsWith("data:") ? dataUrl : `data:image/png;base64,${dataUrl}`;
|
|
1590
|
+
const comma = normalized.indexOf(",");
|
|
1591
|
+
if (comma === -1) {
|
|
1592
|
+
throw new Error("Invalid data URL (missing comma separator)");
|
|
1593
|
+
}
|
|
1594
|
+
const header = normalized.slice(0, comma);
|
|
1595
|
+
const base64 = normalized.slice(comma + 1);
|
|
1596
|
+
const mimeMatch = header.match(/data:(.*?);base64/i);
|
|
1597
|
+
const mimeType = (mimeMatch == null ? void 0 : mimeMatch[1]) ?? "application/octet-stream";
|
|
1598
|
+
const cacheDir = FileSystem2.cacheDirectory;
|
|
1599
|
+
if (!cacheDir) {
|
|
1600
|
+
throw new Error("expo-file-system cacheDirectory is unavailable");
|
|
1601
|
+
}
|
|
1602
|
+
const fileUri = `${cacheDir}attachment-${Date.now()}-${Math.random().toString(16).slice(2)}.bin`;
|
|
1603
|
+
await FileSystem2.writeAsStringAsync(fileUri, base64, {
|
|
1604
|
+
encoding: FileSystem2.EncodingType.Base64
|
|
1605
|
+
});
|
|
1606
|
+
try {
|
|
1607
|
+
const resp = await fetch(fileUri);
|
|
1608
|
+
const blob = await resp.blob();
|
|
1609
|
+
return blob.type ? blob : new Blob([blob], { type: mimeType });
|
|
1610
|
+
} finally {
|
|
1611
|
+
void FileSystem2.deleteAsync(fileUri, { idempotent: true }).catch(() => {
|
|
1612
|
+
});
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
function getMimeTypeFromDataUrl(dataUrl) {
|
|
1616
|
+
const normalized = dataUrl.startsWith("data:") ? dataUrl : `data:image/png;base64,${dataUrl}`;
|
|
1617
|
+
const comma = normalized.indexOf(",");
|
|
1618
|
+
const header = comma === -1 ? normalized : normalized.slice(0, comma);
|
|
1619
|
+
const mimeMatch = header.match(/data:(.*?);base64/i);
|
|
1620
|
+
return (mimeMatch == null ? void 0 : mimeMatch[1]) ?? "image/png";
|
|
1621
|
+
}
|
|
1521
1622
|
function useAttachmentUpload() {
|
|
1522
1623
|
const [uploading, setUploading] = React7.useState(false);
|
|
1523
1624
|
const [error, setError] = React7.useState(null);
|
|
@@ -1530,15 +1631,15 @@ function useAttachmentUpload() {
|
|
|
1530
1631
|
const blobs = await Promise.all(
|
|
1531
1632
|
dataUrls.map(async (dataUrl, idx) => {
|
|
1532
1633
|
const normalized = dataUrl.startsWith("data:") ? dataUrl : `data:image/png;base64,${dataUrl}`;
|
|
1533
|
-
const
|
|
1534
|
-
const
|
|
1535
|
-
return { blob, idx };
|
|
1634
|
+
const blob = Platform.OS === "android" ? await dataUrlToBlobAndroid(normalized) : await (await fetch(normalized)).blob();
|
|
1635
|
+
const mimeType = getMimeTypeFromDataUrl(normalized);
|
|
1636
|
+
return { blob, idx, mimeType };
|
|
1536
1637
|
})
|
|
1537
1638
|
);
|
|
1538
|
-
const files = blobs.map(({ blob }, idx) => ({
|
|
1639
|
+
const files = blobs.map(({ blob, mimeType }, idx) => ({
|
|
1539
1640
|
name: `attachment-${Date.now()}-${idx}.png`,
|
|
1540
1641
|
size: blob.size,
|
|
1541
|
-
mimeType
|
|
1642
|
+
mimeType
|
|
1542
1643
|
}));
|
|
1543
1644
|
const presign = await attachmentRepository.presign({ threadId, appId, files });
|
|
1544
1645
|
await Promise.all(presign.uploads.map((u, index) => attachmentRepository.upload(u, blobs[index].blob)));
|
|
@@ -1665,8 +1766,8 @@ function hasNoOutcomeAfterLastHuman(messages) {
|
|
|
1665
1766
|
import { View as View2 } from "react-native";
|
|
1666
1767
|
import { ComergeRuntimeRenderer } from "@comergehq/runtime";
|
|
1667
1768
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1668
|
-
function RuntimeRenderer({ appKey, bundlePath, renderToken, style }) {
|
|
1669
|
-
if (!bundlePath) {
|
|
1769
|
+
function RuntimeRenderer({ appKey, bundlePath, forcePreparing, renderToken, style }) {
|
|
1770
|
+
if (!bundlePath || forcePreparing) {
|
|
1670
1771
|
return /* @__PURE__ */ jsx3(View2, { style: [{ flex: 1, justifyContent: "center", alignItems: "center", padding: 24 }, style], children: /* @__PURE__ */ jsx3(Text, { variant: "bodyMuted", children: "Preparing app\u2026" }) });
|
|
1671
1772
|
}
|
|
1672
1773
|
return /* @__PURE__ */ jsx3(View2, { style: [{ flex: 1 }, style], children: /* @__PURE__ */ jsx3(
|
|
@@ -1681,25 +1782,76 @@ function RuntimeRenderer({ appKey, bundlePath, renderToken, style }) {
|
|
|
1681
1782
|
}
|
|
1682
1783
|
|
|
1683
1784
|
// src/studio/ui/StudioOverlay.tsx
|
|
1684
|
-
import * as
|
|
1685
|
-
import { Keyboard as Keyboard5, Platform as
|
|
1785
|
+
import * as React41 from "react";
|
|
1786
|
+
import { Keyboard as Keyboard5, Platform as Platform10, View as View44, useWindowDimensions as useWindowDimensions4 } from "react-native";
|
|
1686
1787
|
|
|
1687
1788
|
// src/components/studio-sheet/StudioBottomSheet.tsx
|
|
1688
|
-
import * as
|
|
1689
|
-
import { AppState as
|
|
1789
|
+
import * as React11 from "react";
|
|
1790
|
+
import { AppState as AppState3, Keyboard, View as View4 } from "react-native";
|
|
1690
1791
|
import BottomSheet from "@gorhom/bottom-sheet";
|
|
1691
1792
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
1692
1793
|
|
|
1693
1794
|
// src/components/studio-sheet/StudioSheetBackground.tsx
|
|
1694
|
-
import { Platform, View as View3 } from "react-native";
|
|
1695
|
-
import {
|
|
1696
|
-
|
|
1795
|
+
import { Platform as Platform3, View as View3 } from "react-native";
|
|
1796
|
+
import { isLiquidGlassSupported } from "@callstack/liquid-glass";
|
|
1797
|
+
|
|
1798
|
+
// src/components/utils/ResettableLiquidGlassView.tsx
|
|
1799
|
+
import * as React10 from "react";
|
|
1800
|
+
import { LiquidGlassView } from "@callstack/liquid-glass";
|
|
1801
|
+
|
|
1802
|
+
// src/components/utils/liquidGlassReset.tsx
|
|
1803
|
+
import * as React9 from "react";
|
|
1804
|
+
import { AppState as AppState2, Platform as Platform2 } from "react-native";
|
|
1805
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1806
|
+
var LiquidGlassResetContext = React9.createContext(0);
|
|
1807
|
+
function LiquidGlassResetProvider({
|
|
1808
|
+
children,
|
|
1809
|
+
resetTriggers = []
|
|
1810
|
+
}) {
|
|
1811
|
+
const [token, setToken] = React9.useState(0);
|
|
1812
|
+
React9.useEffect(() => {
|
|
1813
|
+
if (Platform2.OS !== "ios") return;
|
|
1814
|
+
const onChange = (state) => {
|
|
1815
|
+
if (state === "active") setToken((t) => t + 1);
|
|
1816
|
+
};
|
|
1817
|
+
const sub = AppState2.addEventListener("change", onChange);
|
|
1818
|
+
return () => sub.remove();
|
|
1819
|
+
}, []);
|
|
1820
|
+
React9.useEffect(() => {
|
|
1821
|
+
setToken((t) => t + 1);
|
|
1822
|
+
}, resetTriggers);
|
|
1823
|
+
return /* @__PURE__ */ jsx4(LiquidGlassResetContext.Provider, { value: token, children });
|
|
1824
|
+
}
|
|
1825
|
+
function useLiquidGlassResetToken() {
|
|
1826
|
+
return React9.useContext(LiquidGlassResetContext);
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1829
|
+
// src/components/utils/ResettableLiquidGlassView.tsx
|
|
1830
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
1831
|
+
function ResettableLiquidGlassView({ children, ...props }) {
|
|
1832
|
+
const token = useLiquidGlassResetToken();
|
|
1833
|
+
const [layoutBootKey, setLayoutBootKey] = React10.useState(0);
|
|
1834
|
+
const sawNonZeroLayoutRef = React10.useRef(false);
|
|
1835
|
+
const onLayout = (e) => {
|
|
1836
|
+
var _a;
|
|
1837
|
+
(_a = props.onLayout) == null ? void 0 : _a.call(props, e);
|
|
1838
|
+
const { width, height } = e.nativeEvent.layout;
|
|
1839
|
+
if (width > 0 && height > 0 && !sawNonZeroLayoutRef.current) {
|
|
1840
|
+
sawNonZeroLayoutRef.current = true;
|
|
1841
|
+
setLayoutBootKey((k) => k + 1);
|
|
1842
|
+
}
|
|
1843
|
+
};
|
|
1844
|
+
return /* @__PURE__ */ jsx5(LiquidGlassView, { ...props, onLayout, children }, `liquid-glass-${token}-${layoutBootKey}`);
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
// src/components/studio-sheet/StudioSheetBackground.tsx
|
|
1848
|
+
import { Fragment as Fragment2, jsx as jsx6, jsxs } from "react/jsx-runtime";
|
|
1697
1849
|
function StudioSheetBackground({
|
|
1698
1850
|
style,
|
|
1699
1851
|
renderBackground
|
|
1700
1852
|
}) {
|
|
1701
1853
|
const theme = useTheme();
|
|
1702
|
-
const radius =
|
|
1854
|
+
const radius = Platform3.OS === "ios" ? 39 : 16;
|
|
1703
1855
|
const fallbackBgColor = theme.scheme === "dark" ? "rgba(11, 8, 15, 0.85)" : "rgba(255, 255, 255, 0.85)";
|
|
1704
1856
|
const secondaryBgBaseColor = theme.scheme === "dark" ? "rgb(24, 24, 27)" : "rgb(173, 173, 173)";
|
|
1705
1857
|
const containerStyle = {
|
|
@@ -1709,17 +1861,17 @@ function StudioSheetBackground({
|
|
|
1709
1861
|
overflow: "hidden"
|
|
1710
1862
|
};
|
|
1711
1863
|
if (renderBackground) {
|
|
1712
|
-
return /* @__PURE__ */
|
|
1864
|
+
return /* @__PURE__ */ jsx6(Fragment2, { children: renderBackground({ style: containerStyle }) });
|
|
1713
1865
|
}
|
|
1714
1866
|
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
1715
|
-
/* @__PURE__ */
|
|
1716
|
-
|
|
1867
|
+
/* @__PURE__ */ jsx6(
|
|
1868
|
+
ResettableLiquidGlassView,
|
|
1717
1869
|
{
|
|
1718
1870
|
style: [containerStyle, !isLiquidGlassSupported && { backgroundColor: fallbackBgColor }],
|
|
1719
1871
|
effect: "regular"
|
|
1720
1872
|
}
|
|
1721
1873
|
),
|
|
1722
|
-
isLiquidGlassSupported && /* @__PURE__ */
|
|
1874
|
+
isLiquidGlassSupported && /* @__PURE__ */ jsx6(
|
|
1723
1875
|
View3,
|
|
1724
1876
|
{
|
|
1725
1877
|
style: [
|
|
@@ -1741,11 +1893,11 @@ function StudioSheetBackground({
|
|
|
1741
1893
|
}
|
|
1742
1894
|
|
|
1743
1895
|
// src/components/studio-sheet/StudioBottomSheet.tsx
|
|
1744
|
-
import { jsx as
|
|
1896
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1745
1897
|
function StudioBottomSheet({
|
|
1746
1898
|
open,
|
|
1747
1899
|
onOpenChange,
|
|
1748
|
-
snapPoints = ["
|
|
1900
|
+
snapPoints = ["100%"],
|
|
1749
1901
|
sheetRef,
|
|
1750
1902
|
background,
|
|
1751
1903
|
children,
|
|
@@ -1753,12 +1905,12 @@ function StudioBottomSheet({
|
|
|
1753
1905
|
}) {
|
|
1754
1906
|
const theme = useTheme();
|
|
1755
1907
|
const insets = useSafeAreaInsets();
|
|
1756
|
-
const internalSheetRef =
|
|
1908
|
+
const internalSheetRef = React11.useRef(null);
|
|
1757
1909
|
const resolvedSheetRef = sheetRef ?? internalSheetRef;
|
|
1758
|
-
const currentIndexRef =
|
|
1759
|
-
const lastAppStateRef =
|
|
1760
|
-
|
|
1761
|
-
const sub =
|
|
1910
|
+
const currentIndexRef = React11.useRef(open ? snapPoints.length - 1 : -1);
|
|
1911
|
+
const lastAppStateRef = React11.useRef(AppState3.currentState);
|
|
1912
|
+
React11.useEffect(() => {
|
|
1913
|
+
const sub = AppState3.addEventListener("change", (state) => {
|
|
1762
1914
|
const prev = lastAppStateRef.current;
|
|
1763
1915
|
lastAppStateRef.current = state;
|
|
1764
1916
|
if (state === "background" || state === "inactive") {
|
|
@@ -1777,7 +1929,7 @@ function StudioBottomSheet({
|
|
|
1777
1929
|
});
|
|
1778
1930
|
return () => sub.remove();
|
|
1779
1931
|
}, [open, resolvedSheetRef]);
|
|
1780
|
-
|
|
1932
|
+
React11.useEffect(() => {
|
|
1781
1933
|
const sheet = resolvedSheetRef.current;
|
|
1782
1934
|
if (!sheet) return;
|
|
1783
1935
|
if (open) {
|
|
@@ -1786,41 +1938,41 @@ function StudioBottomSheet({
|
|
|
1786
1938
|
sheet.close();
|
|
1787
1939
|
}
|
|
1788
1940
|
}, [open, resolvedSheetRef, snapPoints.length]);
|
|
1789
|
-
const handleChange =
|
|
1941
|
+
const handleChange = React11.useCallback(
|
|
1790
1942
|
(index) => {
|
|
1791
1943
|
currentIndexRef.current = index;
|
|
1792
1944
|
onOpenChange == null ? void 0 : onOpenChange(index >= 0);
|
|
1793
1945
|
},
|
|
1794
1946
|
[onOpenChange]
|
|
1795
1947
|
);
|
|
1796
|
-
return /* @__PURE__ */
|
|
1948
|
+
return /* @__PURE__ */ jsx7(
|
|
1797
1949
|
BottomSheet,
|
|
1798
1950
|
{
|
|
1799
1951
|
ref: resolvedSheetRef,
|
|
1800
1952
|
index: open ? snapPoints.length - 1 : -1,
|
|
1801
1953
|
snapPoints,
|
|
1954
|
+
enableDynamicSizing: false,
|
|
1802
1955
|
enablePanDownToClose: true,
|
|
1803
|
-
|
|
1804
|
-
keyboardBlurBehavior: "restore",
|
|
1956
|
+
enableContentPanningGesture: false,
|
|
1805
1957
|
android_keyboardInputMode: "adjustResize",
|
|
1806
|
-
backgroundComponent: (props) => /* @__PURE__ */
|
|
1958
|
+
backgroundComponent: (props) => /* @__PURE__ */ jsx7(StudioSheetBackground, { ...props, renderBackground: background == null ? void 0 : background.renderBackground }),
|
|
1807
1959
|
topInset: insets.top,
|
|
1808
1960
|
bottomInset: 0,
|
|
1809
1961
|
handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
|
|
1810
1962
|
onChange: handleChange,
|
|
1811
1963
|
...bottomSheetProps,
|
|
1812
|
-
children: /* @__PURE__ */
|
|
1964
|
+
children: /* @__PURE__ */ jsx7(View4, { style: { flex: 1, overflow: "hidden" }, children })
|
|
1813
1965
|
}
|
|
1814
1966
|
);
|
|
1815
1967
|
}
|
|
1816
1968
|
|
|
1817
1969
|
// src/components/studio-sheet/StudioSheetPager.tsx
|
|
1818
|
-
import * as
|
|
1970
|
+
import * as React12 from "react";
|
|
1819
1971
|
import { Animated } from "react-native";
|
|
1820
|
-
import { jsx as
|
|
1972
|
+
import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1821
1973
|
function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
1822
|
-
const anim =
|
|
1823
|
-
|
|
1974
|
+
const anim = React12.useRef(new Animated.Value(activePage === "chat" ? 1 : 0)).current;
|
|
1975
|
+
React12.useEffect(() => {
|
|
1824
1976
|
Animated.spring(anim, {
|
|
1825
1977
|
toValue: activePage === "chat" ? 1 : 0,
|
|
1826
1978
|
useNativeDriver: true,
|
|
@@ -1831,7 +1983,7 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1831
1983
|
const previewTranslateX = anim.interpolate({ inputRange: [0, 1], outputRange: [0, -width] });
|
|
1832
1984
|
const chatTranslateX = anim.interpolate({ inputRange: [0, 1], outputRange: [width, 0] });
|
|
1833
1985
|
return /* @__PURE__ */ jsxs2(Animated.View, { style: [{ flex: 1 }, style], children: [
|
|
1834
|
-
/* @__PURE__ */
|
|
1986
|
+
/* @__PURE__ */ jsx8(
|
|
1835
1987
|
Animated.View,
|
|
1836
1988
|
{
|
|
1837
1989
|
style: [
|
|
@@ -1848,7 +2000,7 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1848
2000
|
children: preview
|
|
1849
2001
|
}
|
|
1850
2002
|
),
|
|
1851
|
-
/* @__PURE__ */
|
|
2003
|
+
/* @__PURE__ */ jsx8(
|
|
1852
2004
|
Animated.View,
|
|
1853
2005
|
{
|
|
1854
2006
|
style: [
|
|
@@ -1869,7 +2021,7 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1869
2021
|
}
|
|
1870
2022
|
|
|
1871
2023
|
// src/components/floating-draggable-button/FloatingDraggableButton.tsx
|
|
1872
|
-
import { useCallback as useCallback8, useEffect as
|
|
2024
|
+
import { useCallback as useCallback8, useEffect as useEffect10, useMemo as useMemo3, useRef as useRef7 } from "react";
|
|
1873
2025
|
import {
|
|
1874
2026
|
PanResponder,
|
|
1875
2027
|
Pressable,
|
|
@@ -1890,7 +2042,7 @@ import Animated2, {
|
|
|
1890
2042
|
withSpring,
|
|
1891
2043
|
withTiming
|
|
1892
2044
|
} from "react-native-reanimated";
|
|
1893
|
-
import {
|
|
2045
|
+
import { isLiquidGlassSupported as isLiquidGlassSupported2 } from "@callstack/liquid-glass";
|
|
1894
2046
|
|
|
1895
2047
|
// src/components/floating-draggable-button/constants.ts
|
|
1896
2048
|
var DEFAULT_SIZE = 48;
|
|
@@ -1901,11 +2053,10 @@ var DEFAULT_OFFSET = {
|
|
|
1901
2053
|
};
|
|
1902
2054
|
var ENTER_SCALE_FROM = 0.3;
|
|
1903
2055
|
var ENTER_ROTATION_FROM_DEG = -180;
|
|
1904
|
-
var HIDDEN_OPACITY = 0.3;
|
|
1905
2056
|
var PULSE_DURATION_MS = 900;
|
|
1906
2057
|
|
|
1907
2058
|
// src/components/floating-draggable-button/FloatingDraggableButton.tsx
|
|
1908
|
-
import { jsx as
|
|
2059
|
+
import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1909
2060
|
var HIDDEN_OFFSET_X = 20;
|
|
1910
2061
|
var SPRING_POSITION = { damping: 12, stiffness: 100, mass: 0.8 };
|
|
1911
2062
|
var SPRING_SCALE_IN = { damping: 10, stiffness: 200 };
|
|
@@ -1913,8 +2064,6 @@ var SPRING_SCALE_OUT = { damping: 12, stiffness: 150 };
|
|
|
1913
2064
|
var SPRING_ROTATION_IN = { damping: 15, stiffness: 80 };
|
|
1914
2065
|
var SPRING_ROTATION_GRAB = { damping: 20 };
|
|
1915
2066
|
var SPRING_SCALE_GRAB = { damping: 15, stiffness: 200 };
|
|
1916
|
-
var TIMING_OPACITY_IN = { duration: 300, easing: Easing.out(Easing.ease) };
|
|
1917
|
-
var TIMING_OPACITY_OUT = { duration: 250, easing: Easing.in(Easing.ease) };
|
|
1918
2067
|
function clamp(value, min, max) {
|
|
1919
2068
|
"worklet";
|
|
1920
2069
|
return Math.max(min, Math.min(max, value));
|
|
@@ -1948,8 +2097,8 @@ function FloatingDraggableButton({
|
|
|
1948
2097
|
const theme = useTheme();
|
|
1949
2098
|
const { width, height } = useWindowDimensions();
|
|
1950
2099
|
const isDanger = variant === "danger";
|
|
1951
|
-
const onPressRef =
|
|
1952
|
-
|
|
2100
|
+
const onPressRef = useRef7(onPress);
|
|
2101
|
+
useEffect10(() => {
|
|
1953
2102
|
onPressRef.current = onPress;
|
|
1954
2103
|
}, [onPress]);
|
|
1955
2104
|
const fallbackBgColor = useMemo3(() => {
|
|
@@ -1961,30 +2110,20 @@ function FloatingDraggableButton({
|
|
|
1961
2110
|
const translateY = useSharedValue(getHiddenTranslateY(height));
|
|
1962
2111
|
const scale = useSharedValue(ENTER_SCALE_FROM);
|
|
1963
2112
|
const rotation = useSharedValue(ENTER_ROTATION_FROM_DEG);
|
|
1964
|
-
const opacity = useSharedValue(1);
|
|
1965
2113
|
const borderPulse = useSharedValue(0);
|
|
1966
|
-
const startPos =
|
|
1967
|
-
const isAnimatingOut =
|
|
2114
|
+
const startPos = useRef7({ x: 0, y: 0 });
|
|
2115
|
+
const isAnimatingOut = useRef7(false);
|
|
1968
2116
|
const animateToHidden = useCallback8(
|
|
1969
2117
|
(options) => {
|
|
1970
|
-
|
|
2118
|
+
const finish = options == null ? void 0 : options.onFinish;
|
|
2119
|
+
translateX.value = withSpring(getHiddenTranslateX(size), SPRING_POSITION, (finished) => {
|
|
2120
|
+
if (finished && finish) runOnJS(finish)();
|
|
2121
|
+
});
|
|
1971
2122
|
translateY.value = withSpring(getHiddenTranslateY(height), SPRING_POSITION);
|
|
1972
2123
|
scale.value = withSpring(ENTER_SCALE_FROM, SPRING_SCALE_IN);
|
|
1973
2124
|
rotation.value = withSpring(ENTER_ROTATION_FROM_DEG, SPRING_ROTATION_IN);
|
|
1974
|
-
const finish = options == null ? void 0 : options.onFinish;
|
|
1975
|
-
if (!finish) {
|
|
1976
|
-
opacity.value = withTiming(HIDDEN_OPACITY, TIMING_OPACITY_OUT);
|
|
1977
|
-
return;
|
|
1978
|
-
}
|
|
1979
|
-
opacity.value = withTiming(
|
|
1980
|
-
HIDDEN_OPACITY,
|
|
1981
|
-
TIMING_OPACITY_OUT,
|
|
1982
|
-
(finished) => {
|
|
1983
|
-
if (finished) runOnJS(finish)();
|
|
1984
|
-
}
|
|
1985
|
-
);
|
|
1986
2125
|
},
|
|
1987
|
-
[height,
|
|
2126
|
+
[height, rotation, scale, size, translateX, translateY]
|
|
1988
2127
|
);
|
|
1989
2128
|
const animateOut = useCallback8(() => {
|
|
1990
2129
|
if (isAnimatingOut.current) return;
|
|
@@ -2000,7 +2139,7 @@ function FloatingDraggableButton({
|
|
|
2000
2139
|
}
|
|
2001
2140
|
});
|
|
2002
2141
|
}, [animateToHidden]);
|
|
2003
|
-
|
|
2142
|
+
useEffect10(() => {
|
|
2004
2143
|
if (isLoading) {
|
|
2005
2144
|
borderPulse.value = withRepeat(
|
|
2006
2145
|
withSequence(
|
|
@@ -2024,9 +2163,8 @@ function FloatingDraggableButton({
|
|
|
2024
2163
|
withSpring(1, SPRING_SCALE_OUT)
|
|
2025
2164
|
);
|
|
2026
2165
|
rotation.value = withSpring(0, SPRING_ROTATION_IN);
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
useEffect9(() => {
|
|
2166
|
+
}, [height, offset.bottom, offset.left, rotation, scale, size, translateX, translateY]);
|
|
2167
|
+
useEffect10(() => {
|
|
2030
2168
|
const timer = setTimeout(() => {
|
|
2031
2169
|
if (visible) {
|
|
2032
2170
|
animateIn();
|
|
@@ -2034,7 +2172,7 @@ function FloatingDraggableButton({
|
|
|
2034
2172
|
}, 100);
|
|
2035
2173
|
return () => clearTimeout(timer);
|
|
2036
2174
|
}, []);
|
|
2037
|
-
|
|
2175
|
+
useEffect10(() => {
|
|
2038
2176
|
if (visible && isAnimatingOut.current) {
|
|
2039
2177
|
animateIn();
|
|
2040
2178
|
} else if (!visible && !isAnimatingOut.current) {
|
|
@@ -2042,13 +2180,13 @@ function FloatingDraggableButton({
|
|
|
2042
2180
|
isAnimatingOut.current = true;
|
|
2043
2181
|
}
|
|
2044
2182
|
}, [visible, animateIn, animateToHidden]);
|
|
2045
|
-
|
|
2183
|
+
useEffect10(() => {
|
|
2046
2184
|
if (forceShowTrigger > 0 && visible) {
|
|
2047
2185
|
isAnimatingOut.current = false;
|
|
2048
2186
|
animateIn();
|
|
2049
2187
|
}
|
|
2050
2188
|
}, [forceShowTrigger, visible, animateIn]);
|
|
2051
|
-
const panResponder =
|
|
2189
|
+
const panResponder = useRef7(
|
|
2052
2190
|
PanResponder.create({
|
|
2053
2191
|
onStartShouldSetPanResponder: () => true,
|
|
2054
2192
|
onMoveShouldSetPanResponder: () => true,
|
|
@@ -2081,8 +2219,7 @@ function FloatingDraggableButton({
|
|
|
2081
2219
|
{ translateY: translateY.value },
|
|
2082
2220
|
{ scale: scale.value },
|
|
2083
2221
|
{ rotate: `${rotation.value}deg` }
|
|
2084
|
-
]
|
|
2085
|
-
opacity: opacity.value
|
|
2222
|
+
]
|
|
2086
2223
|
}));
|
|
2087
2224
|
const borderAnimatedStyle = useAnimatedStyle(() => {
|
|
2088
2225
|
const borderColor = interpolateColor(
|
|
@@ -2105,13 +2242,13 @@ function FloatingDraggableButton({
|
|
|
2105
2242
|
accessibilityRole: "button",
|
|
2106
2243
|
accessibilityLabel: ariaLabel,
|
|
2107
2244
|
children: [
|
|
2108
|
-
/* @__PURE__ */
|
|
2109
|
-
|
|
2245
|
+
/* @__PURE__ */ jsx9(Animated2.View, { style: [{ width: size, height: size, borderRadius: size / 2 }, borderAnimatedStyle], children: /* @__PURE__ */ jsx9(
|
|
2246
|
+
ResettableLiquidGlassView,
|
|
2110
2247
|
{
|
|
2111
2248
|
style: [{ flex: 1, borderRadius: size / 2 }, !isLiquidGlassSupported2 && { backgroundColor: fallbackBgColor }],
|
|
2112
2249
|
interactive: true,
|
|
2113
2250
|
effect: "clear",
|
|
2114
|
-
children: /* @__PURE__ */
|
|
2251
|
+
children: /* @__PURE__ */ jsx9(
|
|
2115
2252
|
Pressable,
|
|
2116
2253
|
{
|
|
2117
2254
|
onPress: () => {
|
|
@@ -2119,12 +2256,12 @@ function FloatingDraggableButton({
|
|
|
2119
2256
|
},
|
|
2120
2257
|
style: styles.buttonInner,
|
|
2121
2258
|
android_ripple: { color: "rgba(255, 255, 255, 0.3)", borderless: true },
|
|
2122
|
-
children: children ?? /* @__PURE__ */
|
|
2259
|
+
children: children ?? /* @__PURE__ */ jsx9(View5, {})
|
|
2123
2260
|
}
|
|
2124
2261
|
)
|
|
2125
2262
|
}
|
|
2126
2263
|
) }),
|
|
2127
|
-
badgeCount > 0 && /* @__PURE__ */
|
|
2264
|
+
badgeCount > 0 && /* @__PURE__ */ jsx9(View5, { style: [styles.badge, { backgroundColor: theme.colors.danger }], children: /* @__PURE__ */ jsx9(Text2, { style: [styles.badgeText, { color: theme.colors.onDanger }], children: badgeCount > 99 ? "99+" : badgeCount }) })
|
|
2128
2265
|
]
|
|
2129
2266
|
}
|
|
2130
2267
|
);
|
|
@@ -2165,7 +2302,7 @@ var styles = StyleSheet.create({
|
|
|
2165
2302
|
});
|
|
2166
2303
|
|
|
2167
2304
|
// src/components/overlays/EdgeGlowFrame.tsx
|
|
2168
|
-
import * as
|
|
2305
|
+
import * as React13 from "react";
|
|
2169
2306
|
import { Animated as Animated3, View as View6 } from "react-native";
|
|
2170
2307
|
import { LinearGradient } from "expo-linear-gradient";
|
|
2171
2308
|
|
|
@@ -2185,7 +2322,7 @@ function withAlpha(color, alpha) {
|
|
|
2185
2322
|
}
|
|
2186
2323
|
|
|
2187
2324
|
// src/components/overlays/EdgeGlowFrame.tsx
|
|
2188
|
-
import { jsx as
|
|
2325
|
+
import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2189
2326
|
function baseColor(role, theme) {
|
|
2190
2327
|
switch (role) {
|
|
2191
2328
|
case "danger":
|
|
@@ -2208,8 +2345,8 @@ function EdgeGlowFrame({
|
|
|
2208
2345
|
}) {
|
|
2209
2346
|
const theme = useTheme();
|
|
2210
2347
|
const alpha = Math.max(0, Math.min(1, intensity));
|
|
2211
|
-
const anim =
|
|
2212
|
-
|
|
2348
|
+
const anim = React13.useRef(new Animated3.Value(visible ? 1 : 0)).current;
|
|
2349
|
+
React13.useEffect(() => {
|
|
2213
2350
|
Animated3.timing(anim, {
|
|
2214
2351
|
toValue: visible ? 1 : 0,
|
|
2215
2352
|
duration: 300,
|
|
@@ -2220,7 +2357,7 @@ function EdgeGlowFrame({
|
|
|
2220
2357
|
const strong = withAlpha(c, 0.6 * alpha);
|
|
2221
2358
|
const soft = withAlpha(c, 0.22 * alpha);
|
|
2222
2359
|
return /* @__PURE__ */ jsxs4(Animated3.View, { pointerEvents: "none", style: [{ position: "absolute", inset: 0, opacity: anim }, style], children: [
|
|
2223
|
-
/* @__PURE__ */
|
|
2360
|
+
/* @__PURE__ */ jsx10(View6, { style: { position: "absolute", top: 0, left: 0, right: 0, height: thickness }, children: /* @__PURE__ */ jsx10(
|
|
2224
2361
|
LinearGradient,
|
|
2225
2362
|
{
|
|
2226
2363
|
colors: [strong, soft, "transparent"],
|
|
@@ -2229,7 +2366,7 @@ function EdgeGlowFrame({
|
|
|
2229
2366
|
style: { width: "100%", height: "100%" }
|
|
2230
2367
|
}
|
|
2231
2368
|
) }),
|
|
2232
|
-
/* @__PURE__ */
|
|
2369
|
+
/* @__PURE__ */ jsx10(View6, { style: { position: "absolute", bottom: 0, left: 0, right: 0, height: thickness }, children: /* @__PURE__ */ jsx10(
|
|
2233
2370
|
LinearGradient,
|
|
2234
2371
|
{
|
|
2235
2372
|
colors: ["transparent", soft, strong],
|
|
@@ -2238,7 +2375,7 @@ function EdgeGlowFrame({
|
|
|
2238
2375
|
style: { width: "100%", height: "100%" }
|
|
2239
2376
|
}
|
|
2240
2377
|
) }),
|
|
2241
|
-
/* @__PURE__ */
|
|
2378
|
+
/* @__PURE__ */ jsx10(View6, { style: { position: "absolute", top: 0, bottom: 0, left: 0, width: thickness }, children: /* @__PURE__ */ jsx10(
|
|
2242
2379
|
LinearGradient,
|
|
2243
2380
|
{
|
|
2244
2381
|
colors: [strong, soft, "transparent"],
|
|
@@ -2247,7 +2384,7 @@ function EdgeGlowFrame({
|
|
|
2247
2384
|
style: { width: "100%", height: "100%" }
|
|
2248
2385
|
}
|
|
2249
2386
|
) }),
|
|
2250
|
-
/* @__PURE__ */
|
|
2387
|
+
/* @__PURE__ */ jsx10(View6, { style: { position: "absolute", top: 0, bottom: 0, right: 0, width: thickness }, children: /* @__PURE__ */ jsx10(
|
|
2251
2388
|
LinearGradient,
|
|
2252
2389
|
{
|
|
2253
2390
|
colors: ["transparent", soft, strong],
|
|
@@ -2260,12 +2397,12 @@ function EdgeGlowFrame({
|
|
|
2260
2397
|
}
|
|
2261
2398
|
|
|
2262
2399
|
// src/components/draw/DrawModeOverlay.tsx
|
|
2263
|
-
import * as
|
|
2400
|
+
import * as React16 from "react";
|
|
2264
2401
|
import { StyleSheet as StyleSheet3, View as View10 } from "react-native";
|
|
2265
2402
|
import { captureRef } from "react-native-view-shot";
|
|
2266
2403
|
|
|
2267
2404
|
// src/components/draw/DrawSurface.tsx
|
|
2268
|
-
import * as
|
|
2405
|
+
import * as React14 from "react";
|
|
2269
2406
|
import { PanResponder as PanResponder2, StyleSheet as StyleSheet2, View as View7 } from "react-native";
|
|
2270
2407
|
import Svg, { Path } from "react-native-svg";
|
|
2271
2408
|
|
|
@@ -2288,7 +2425,7 @@ function pointsToSmoothPath(points) {
|
|
|
2288
2425
|
}
|
|
2289
2426
|
|
|
2290
2427
|
// src/components/draw/DrawSurface.tsx
|
|
2291
|
-
import { jsx as
|
|
2428
|
+
import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2292
2429
|
function DrawSurface({
|
|
2293
2430
|
color,
|
|
2294
2431
|
strokeWidth,
|
|
@@ -2297,25 +2434,25 @@ function DrawSurface({
|
|
|
2297
2434
|
style,
|
|
2298
2435
|
minDistance = 1
|
|
2299
2436
|
}) {
|
|
2300
|
-
const [renderTick, setRenderTick] =
|
|
2301
|
-
const currentPointsRef =
|
|
2302
|
-
const rafRef =
|
|
2303
|
-
const triggerRender =
|
|
2437
|
+
const [renderTick, setRenderTick] = React14.useState(0);
|
|
2438
|
+
const currentPointsRef = React14.useRef([]);
|
|
2439
|
+
const rafRef = React14.useRef(null);
|
|
2440
|
+
const triggerRender = React14.useCallback(() => {
|
|
2304
2441
|
if (rafRef.current !== null) return;
|
|
2305
2442
|
rafRef.current = requestAnimationFrame(() => {
|
|
2306
2443
|
rafRef.current = null;
|
|
2307
2444
|
setRenderTick((n) => n + 1);
|
|
2308
2445
|
});
|
|
2309
2446
|
}, []);
|
|
2310
|
-
|
|
2447
|
+
React14.useEffect(() => () => {
|
|
2311
2448
|
if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);
|
|
2312
2449
|
}, []);
|
|
2313
|
-
const onStart =
|
|
2450
|
+
const onStart = React14.useCallback((e) => {
|
|
2314
2451
|
const { locationX, locationY } = e.nativeEvent;
|
|
2315
2452
|
currentPointsRef.current = [{ x: locationX, y: locationY }];
|
|
2316
2453
|
triggerRender();
|
|
2317
2454
|
}, [triggerRender]);
|
|
2318
|
-
const onMove =
|
|
2455
|
+
const onMove = React14.useCallback((e, _g) => {
|
|
2319
2456
|
const { locationX, locationY } = e.nativeEvent;
|
|
2320
2457
|
const pts = currentPointsRef.current;
|
|
2321
2458
|
if (pts.length > 0) {
|
|
@@ -2328,7 +2465,7 @@ function DrawSurface({
|
|
|
2328
2465
|
currentPointsRef.current = [...pts, { x: locationX, y: locationY }];
|
|
2329
2466
|
triggerRender();
|
|
2330
2467
|
}, [minDistance, triggerRender]);
|
|
2331
|
-
const onEnd =
|
|
2468
|
+
const onEnd = React14.useCallback(() => {
|
|
2332
2469
|
const points = currentPointsRef.current;
|
|
2333
2470
|
if (points.length > 0) {
|
|
2334
2471
|
onAddStroke({ points, color, width: strokeWidth });
|
|
@@ -2336,7 +2473,7 @@ function DrawSurface({
|
|
|
2336
2473
|
currentPointsRef.current = [];
|
|
2337
2474
|
triggerRender();
|
|
2338
2475
|
}, [color, onAddStroke, strokeWidth, triggerRender]);
|
|
2339
|
-
const panResponder =
|
|
2476
|
+
const panResponder = React14.useMemo(
|
|
2340
2477
|
() => PanResponder2.create({
|
|
2341
2478
|
onStartShouldSetPanResponder: () => true,
|
|
2342
2479
|
onMoveShouldSetPanResponder: () => true,
|
|
@@ -2349,11 +2486,11 @@ function DrawSurface({
|
|
|
2349
2486
|
);
|
|
2350
2487
|
const currentPath = pointsToSmoothPath(currentPointsRef.current);
|
|
2351
2488
|
void renderTick;
|
|
2352
|
-
return /* @__PURE__ */
|
|
2489
|
+
return /* @__PURE__ */ jsx11(View7, { style: [StyleSheet2.absoluteFill, styles2.container, style], ...panResponder.panHandlers, children: /* @__PURE__ */ jsxs5(Svg, { style: StyleSheet2.absoluteFill, width: "100%", height: "100%", children: [
|
|
2353
2490
|
strokes.map((s, idx) => {
|
|
2354
2491
|
const d = pointsToSmoothPath(s.points);
|
|
2355
2492
|
if (!d) return null;
|
|
2356
|
-
return /* @__PURE__ */
|
|
2493
|
+
return /* @__PURE__ */ jsx11(
|
|
2357
2494
|
Path,
|
|
2358
2495
|
{
|
|
2359
2496
|
d,
|
|
@@ -2366,7 +2503,7 @@ function DrawSurface({
|
|
|
2366
2503
|
idx
|
|
2367
2504
|
);
|
|
2368
2505
|
}),
|
|
2369
|
-
currentPath ? /* @__PURE__ */
|
|
2506
|
+
currentPath ? /* @__PURE__ */ jsx11(
|
|
2370
2507
|
Path,
|
|
2371
2508
|
{
|
|
2372
2509
|
d: currentPath,
|
|
@@ -2386,7 +2523,7 @@ var styles2 = StyleSheet2.create({
|
|
|
2386
2523
|
});
|
|
2387
2524
|
|
|
2388
2525
|
// src/components/draw/DrawToolbar.tsx
|
|
2389
|
-
import * as
|
|
2526
|
+
import * as React15 from "react";
|
|
2390
2527
|
import {
|
|
2391
2528
|
ActivityIndicator,
|
|
2392
2529
|
Animated as Animated4,
|
|
@@ -2414,7 +2551,7 @@ async function impact(style) {
|
|
|
2414
2551
|
|
|
2415
2552
|
// src/components/draw/DrawColorPicker.tsx
|
|
2416
2553
|
import { Pressable as Pressable2, View as View8 } from "react-native";
|
|
2417
|
-
import { jsx as
|
|
2554
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
2418
2555
|
function DrawColorPicker({
|
|
2419
2556
|
colors,
|
|
2420
2557
|
selected,
|
|
@@ -2448,9 +2585,9 @@ function DrawColorPicker({
|
|
|
2448
2585
|
return { ...base, ...selectedStyle, ...whiteStyle };
|
|
2449
2586
|
};
|
|
2450
2587
|
if (!expanded) {
|
|
2451
|
-
return /* @__PURE__ */
|
|
2588
|
+
return /* @__PURE__ */ jsx12(Pressable2, { onPress: onToggle, style: [swatchStyle(selected, true), style] });
|
|
2452
2589
|
}
|
|
2453
|
-
return /* @__PURE__ */
|
|
2590
|
+
return /* @__PURE__ */ jsx12(View8, { style: [{ flexDirection: "row", alignItems: "center", gap: 8 }, style], children: colors.map((c, idx) => /* @__PURE__ */ jsx12(
|
|
2454
2591
|
Pressable2,
|
|
2455
2592
|
{
|
|
2456
2593
|
onPress: () => {
|
|
@@ -2464,7 +2601,7 @@ function DrawColorPicker({
|
|
|
2464
2601
|
}
|
|
2465
2602
|
|
|
2466
2603
|
// src/components/draw/DrawToolbar.tsx
|
|
2467
|
-
import { jsx as
|
|
2604
|
+
import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2468
2605
|
function DrawToolbar({
|
|
2469
2606
|
colors,
|
|
2470
2607
|
selectedColor,
|
|
@@ -2483,11 +2620,11 @@ function DrawToolbar({
|
|
|
2483
2620
|
}) {
|
|
2484
2621
|
const insets = useSafeAreaInsets2();
|
|
2485
2622
|
const { width: screenWidth, height: screenHeight } = useWindowDimensions2();
|
|
2486
|
-
const [expanded, setExpanded] =
|
|
2487
|
-
const pos =
|
|
2488
|
-
const start =
|
|
2489
|
-
const currentPos =
|
|
2490
|
-
|
|
2623
|
+
const [expanded, setExpanded] = React15.useState(false);
|
|
2624
|
+
const pos = React15.useRef(new Animated4.ValueXY({ x: screenWidth / 2 - 110, y: -140 })).current;
|
|
2625
|
+
const start = React15.useRef({ x: 0, y: 0 });
|
|
2626
|
+
const currentPos = React15.useRef({ x: 0, y: 0 });
|
|
2627
|
+
React15.useEffect(() => {
|
|
2491
2628
|
if (hidden) return;
|
|
2492
2629
|
Animated4.spring(pos.y, {
|
|
2493
2630
|
toValue: insets.top + 60,
|
|
@@ -2497,7 +2634,7 @@ function DrawToolbar({
|
|
|
2497
2634
|
mass: 0.8
|
|
2498
2635
|
}).start();
|
|
2499
2636
|
}, [hidden, insets.top, pos.y]);
|
|
2500
|
-
|
|
2637
|
+
React15.useEffect(() => {
|
|
2501
2638
|
const id = pos.addListener((v) => {
|
|
2502
2639
|
currentPos.current = { x: v.x ?? 0, y: v.y ?? 0 };
|
|
2503
2640
|
});
|
|
@@ -2505,7 +2642,7 @@ function DrawToolbar({
|
|
|
2505
2642
|
pos.removeListener(id);
|
|
2506
2643
|
};
|
|
2507
2644
|
}, [pos]);
|
|
2508
|
-
const clamp2 =
|
|
2645
|
+
const clamp2 = React15.useCallback(
|
|
2509
2646
|
(x, y) => {
|
|
2510
2647
|
const minX = 10;
|
|
2511
2648
|
const maxX = Math.max(10, screenWidth - 230);
|
|
@@ -2515,7 +2652,7 @@ function DrawToolbar({
|
|
|
2515
2652
|
},
|
|
2516
2653
|
[insets.top, screenHeight, screenWidth]
|
|
2517
2654
|
);
|
|
2518
|
-
const panResponder =
|
|
2655
|
+
const panResponder = React15.useMemo(
|
|
2519
2656
|
() => PanResponder3.create({
|
|
2520
2657
|
onStartShouldSetPanResponder: () => false,
|
|
2521
2658
|
onMoveShouldSetPanResponder: (_e, g) => Math.abs(g.dx) > 5 || Math.abs(g.dy) > 5,
|
|
@@ -2543,8 +2680,8 @@ function DrawToolbar({
|
|
|
2543
2680
|
children
|
|
2544
2681
|
}) {
|
|
2545
2682
|
const isDisabled = Boolean(disabled) || Boolean(capturingDisabled);
|
|
2546
|
-
const [pressed, setPressed] =
|
|
2547
|
-
return /* @__PURE__ */
|
|
2683
|
+
const [pressed, setPressed] = React15.useState(false);
|
|
2684
|
+
return /* @__PURE__ */ jsx13(
|
|
2548
2685
|
View9,
|
|
2549
2686
|
{
|
|
2550
2687
|
style: {
|
|
@@ -2556,7 +2693,7 @@ function DrawToolbar({
|
|
|
2556
2693
|
backgroundColor,
|
|
2557
2694
|
opacity: isDisabled ? 0.5 : pressed ? 0.85 : 1
|
|
2558
2695
|
},
|
|
2559
|
-
children: /* @__PURE__ */
|
|
2696
|
+
children: /* @__PURE__ */ jsx13(
|
|
2560
2697
|
Pressable3,
|
|
2561
2698
|
{
|
|
2562
2699
|
accessibilityRole: "button",
|
|
@@ -2573,7 +2710,7 @@ function DrawToolbar({
|
|
|
2573
2710
|
}
|
|
2574
2711
|
);
|
|
2575
2712
|
}
|
|
2576
|
-
return /* @__PURE__ */
|
|
2713
|
+
return /* @__PURE__ */ jsx13(
|
|
2577
2714
|
Animated4.View,
|
|
2578
2715
|
{
|
|
2579
2716
|
style: [
|
|
@@ -2590,7 +2727,7 @@ function DrawToolbar({
|
|
|
2590
2727
|
style
|
|
2591
2728
|
],
|
|
2592
2729
|
...panResponder.panHandlers,
|
|
2593
|
-
children: /* @__PURE__ */
|
|
2730
|
+
children: /* @__PURE__ */ jsx13(
|
|
2594
2731
|
View9,
|
|
2595
2732
|
{
|
|
2596
2733
|
style: {
|
|
@@ -2600,8 +2737,8 @@ function DrawToolbar({
|
|
|
2600
2737
|
minWidth: 220
|
|
2601
2738
|
},
|
|
2602
2739
|
children: /* @__PURE__ */ jsxs6(View9, { style: { flexDirection: "row", alignItems: "center", gap: 8 }, children: [
|
|
2603
|
-
renderDragHandle ? renderDragHandle() : /* @__PURE__ */
|
|
2604
|
-
/* @__PURE__ */
|
|
2740
|
+
renderDragHandle ? renderDragHandle() : /* @__PURE__ */ jsx13(GripVertical, { size: 20, color: "rgba(255, 255, 255, 0.6)" }),
|
|
2741
|
+
/* @__PURE__ */ jsx13(
|
|
2605
2742
|
DrawColorPicker,
|
|
2606
2743
|
{
|
|
2607
2744
|
colors,
|
|
@@ -2617,8 +2754,8 @@ function DrawToolbar({
|
|
|
2617
2754
|
}
|
|
2618
2755
|
}
|
|
2619
2756
|
),
|
|
2620
|
-
/* @__PURE__ */
|
|
2621
|
-
/* @__PURE__ */
|
|
2757
|
+
/* @__PURE__ */ jsx13(View9, { style: { width: 1, height: 20, backgroundColor: "rgba(255, 255, 255, 0.3)", marginHorizontal: 4 } }),
|
|
2758
|
+
/* @__PURE__ */ jsx13(
|
|
2622
2759
|
CircleActionButton,
|
|
2623
2760
|
{
|
|
2624
2761
|
accessibilityLabel: "Undo",
|
|
@@ -2629,10 +2766,10 @@ function DrawToolbar({
|
|
|
2629
2766
|
void impact("light");
|
|
2630
2767
|
onUndo();
|
|
2631
2768
|
},
|
|
2632
|
-
children: renderUndoIcon ? renderUndoIcon() : /* @__PURE__ */
|
|
2769
|
+
children: renderUndoIcon ? renderUndoIcon() : /* @__PURE__ */ jsx13(Undo2, { size: 16, color: canUndo ? "#FFFFFF" : "rgba(255,255,255,0.4)" })
|
|
2633
2770
|
}
|
|
2634
2771
|
),
|
|
2635
|
-
/* @__PURE__ */
|
|
2772
|
+
/* @__PURE__ */ jsx13(
|
|
2636
2773
|
CircleActionButton,
|
|
2637
2774
|
{
|
|
2638
2775
|
accessibilityLabel: "Cancel",
|
|
@@ -2642,10 +2779,10 @@ function DrawToolbar({
|
|
|
2642
2779
|
void impact("medium");
|
|
2643
2780
|
onCancel();
|
|
2644
2781
|
},
|
|
2645
|
-
children: renderCancelIcon ? renderCancelIcon() : /* @__PURE__ */
|
|
2782
|
+
children: renderCancelIcon ? renderCancelIcon() : /* @__PURE__ */ jsx13(X, { size: 16, color: "#FFFFFF" })
|
|
2646
2783
|
}
|
|
2647
2784
|
),
|
|
2648
|
-
/* @__PURE__ */
|
|
2785
|
+
/* @__PURE__ */ jsx13(
|
|
2649
2786
|
CircleActionButton,
|
|
2650
2787
|
{
|
|
2651
2788
|
accessibilityLabel: "Done",
|
|
@@ -2655,7 +2792,7 @@ function DrawToolbar({
|
|
|
2655
2792
|
void impact("medium");
|
|
2656
2793
|
onDone();
|
|
2657
2794
|
},
|
|
2658
|
-
children: capturing ? /* @__PURE__ */
|
|
2795
|
+
children: capturing ? /* @__PURE__ */ jsx13(ActivityIndicator, { color: "#FFFFFF", size: "small" }) : renderDoneIcon ? renderDoneIcon() : /* @__PURE__ */ jsx13(Check, { size: 16, color: "#FFFFFF" })
|
|
2659
2796
|
}
|
|
2660
2797
|
)
|
|
2661
2798
|
] })
|
|
@@ -2666,7 +2803,7 @@ function DrawToolbar({
|
|
|
2666
2803
|
}
|
|
2667
2804
|
|
|
2668
2805
|
// src/components/draw/DrawModeOverlay.tsx
|
|
2669
|
-
import { jsx as
|
|
2806
|
+
import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2670
2807
|
function DrawModeOverlay({
|
|
2671
2808
|
visible,
|
|
2672
2809
|
captureTargetRef,
|
|
@@ -2681,7 +2818,7 @@ function DrawModeOverlay({
|
|
|
2681
2818
|
renderDragHandle
|
|
2682
2819
|
}) {
|
|
2683
2820
|
const theme = useTheme();
|
|
2684
|
-
const defaultPalette =
|
|
2821
|
+
const defaultPalette = React16.useMemo(
|
|
2685
2822
|
() => [
|
|
2686
2823
|
"#EF4444",
|
|
2687
2824
|
// Red
|
|
@@ -2699,11 +2836,11 @@ function DrawModeOverlay({
|
|
|
2699
2836
|
[]
|
|
2700
2837
|
);
|
|
2701
2838
|
const colors = palette && palette.length > 0 ? palette : defaultPalette;
|
|
2702
|
-
const [selectedColor, setSelectedColor] =
|
|
2703
|
-
const [strokes, setStrokes] =
|
|
2704
|
-
const [capturing, setCapturing] =
|
|
2705
|
-
const [hideUi, setHideUi] =
|
|
2706
|
-
|
|
2839
|
+
const [selectedColor, setSelectedColor] = React16.useState(colors[0] ?? "#EF4444");
|
|
2840
|
+
const [strokes, setStrokes] = React16.useState([]);
|
|
2841
|
+
const [capturing, setCapturing] = React16.useState(false);
|
|
2842
|
+
const [hideUi, setHideUi] = React16.useState(false);
|
|
2843
|
+
React16.useEffect(() => {
|
|
2707
2844
|
if (!visible) return;
|
|
2708
2845
|
setStrokes([]);
|
|
2709
2846
|
setSelectedColor(colors[0] ?? "#EF4444");
|
|
@@ -2711,14 +2848,14 @@ function DrawModeOverlay({
|
|
|
2711
2848
|
setHideUi(false);
|
|
2712
2849
|
}, [colors, visible]);
|
|
2713
2850
|
const canUndo = strokes.length > 0;
|
|
2714
|
-
const handleUndo =
|
|
2851
|
+
const handleUndo = React16.useCallback(() => {
|
|
2715
2852
|
setStrokes((prev) => prev.slice(0, -1));
|
|
2716
2853
|
}, []);
|
|
2717
|
-
const handleCancel =
|
|
2854
|
+
const handleCancel = React16.useCallback(() => {
|
|
2718
2855
|
setStrokes([]);
|
|
2719
2856
|
onCancel();
|
|
2720
2857
|
}, [onCancel]);
|
|
2721
|
-
const handleDone =
|
|
2858
|
+
const handleDone = React16.useCallback(async () => {
|
|
2722
2859
|
if (!captureTargetRef.current || capturing) return;
|
|
2723
2860
|
try {
|
|
2724
2861
|
setCapturing(true);
|
|
@@ -2741,8 +2878,8 @@ function DrawModeOverlay({
|
|
|
2741
2878
|
}, [captureTargetRef, capturing, onCapture]);
|
|
2742
2879
|
if (!visible) return null;
|
|
2743
2880
|
return /* @__PURE__ */ jsxs7(View10, { style: [StyleSheet3.absoluteFill, styles3.root, style], pointerEvents: "box-none", children: [
|
|
2744
|
-
/* @__PURE__ */
|
|
2745
|
-
/* @__PURE__ */
|
|
2881
|
+
/* @__PURE__ */ jsx14(EdgeGlowFrame, { visible: !hideUi, role: "danger", thickness: 50, intensity: 1 }),
|
|
2882
|
+
/* @__PURE__ */ jsx14(
|
|
2746
2883
|
DrawSurface,
|
|
2747
2884
|
{
|
|
2748
2885
|
color: selectedColor,
|
|
@@ -2751,7 +2888,7 @@ function DrawModeOverlay({
|
|
|
2751
2888
|
onAddStroke: (stroke) => setStrokes((prev) => [...prev, stroke])
|
|
2752
2889
|
}
|
|
2753
2890
|
),
|
|
2754
|
-
/* @__PURE__ */
|
|
2891
|
+
/* @__PURE__ */ jsx14(
|
|
2755
2892
|
DrawToolbar,
|
|
2756
2893
|
{
|
|
2757
2894
|
hidden: hideUi,
|
|
@@ -2778,19 +2915,19 @@ var styles3 = StyleSheet3.create({
|
|
|
2778
2915
|
});
|
|
2779
2916
|
|
|
2780
2917
|
// src/components/comments/AppCommentsSheet.tsx
|
|
2781
|
-
import * as
|
|
2782
|
-
import { ActivityIndicator as ActivityIndicator3, Keyboard as Keyboard3, Platform as
|
|
2918
|
+
import * as React23 from "react";
|
|
2919
|
+
import { ActivityIndicator as ActivityIndicator3, Keyboard as Keyboard3, Platform as Platform6, Pressable as Pressable5, View as View14 } from "react-native";
|
|
2783
2920
|
import {
|
|
2784
2921
|
BottomSheetBackdrop,
|
|
2785
2922
|
BottomSheetModal,
|
|
2786
2923
|
BottomSheetScrollView
|
|
2787
2924
|
} from "@gorhom/bottom-sheet";
|
|
2788
2925
|
import { useSafeAreaInsets as useSafeAreaInsets3 } from "react-native-safe-area-context";
|
|
2789
|
-
import {
|
|
2926
|
+
import { isLiquidGlassSupported as isLiquidGlassSupported4 } from "@callstack/liquid-glass";
|
|
2790
2927
|
import { Play as Play2 } from "lucide-react-native";
|
|
2791
2928
|
|
|
2792
2929
|
// src/components/chat/ChatComposer.tsx
|
|
2793
|
-
import * as
|
|
2930
|
+
import * as React18 from "react";
|
|
2794
2931
|
import {
|
|
2795
2932
|
ActivityIndicator as ActivityIndicator2,
|
|
2796
2933
|
Animated as Animated5,
|
|
@@ -2800,15 +2937,15 @@ import {
|
|
|
2800
2937
|
ScrollView,
|
|
2801
2938
|
View as View11
|
|
2802
2939
|
} from "react-native";
|
|
2803
|
-
import {
|
|
2940
|
+
import { isLiquidGlassSupported as isLiquidGlassSupported3 } from "@callstack/liquid-glass";
|
|
2804
2941
|
import { Plus } from "lucide-react-native";
|
|
2805
2942
|
|
|
2806
2943
|
// src/components/chat/MultilineTextInput.tsx
|
|
2807
|
-
import * as
|
|
2944
|
+
import * as React17 from "react";
|
|
2808
2945
|
import { TextInput } from "react-native";
|
|
2809
2946
|
import { BottomSheetTextInput } from "@gorhom/bottom-sheet";
|
|
2810
|
-
import { jsx as
|
|
2811
|
-
var MultilineTextInput =
|
|
2947
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
2948
|
+
var MultilineTextInput = React17.forwardRef(function MultilineTextInput2({ useBottomSheetTextInput = false, placeholder, placeholderTextColor, style, ...props }, ref) {
|
|
2812
2949
|
const theme = useTheme();
|
|
2813
2950
|
const baseStyle = {
|
|
2814
2951
|
minHeight: 44,
|
|
@@ -2828,7 +2965,7 @@ var MultilineTextInput = React15.forwardRef(function MultilineTextInput2({ useBo
|
|
|
2828
2965
|
style: [baseStyle, style],
|
|
2829
2966
|
textAlignVertical: "top"
|
|
2830
2967
|
};
|
|
2831
|
-
return useBottomSheetTextInput ? /* @__PURE__ */
|
|
2968
|
+
return useBottomSheetTextInput ? /* @__PURE__ */ jsx15(BottomSheetTextInput, { ref, ...commonProps }) : /* @__PURE__ */ jsx15(TextInput, { ref, ...commonProps });
|
|
2832
2969
|
});
|
|
2833
2970
|
|
|
2834
2971
|
// src/components/icons/StudioIcons.tsx
|
|
@@ -2845,7 +2982,7 @@ import {
|
|
|
2845
2982
|
X as X2,
|
|
2846
2983
|
Check as Check2
|
|
2847
2984
|
} from "lucide-react-native";
|
|
2848
|
-
import { jsx as
|
|
2985
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
2849
2986
|
function useResolvedIconColor(token) {
|
|
2850
2987
|
const theme = useTheme();
|
|
2851
2988
|
switch (token) {
|
|
@@ -2869,7 +3006,7 @@ function useResolvedIconColor(token) {
|
|
|
2869
3006
|
function makeIcon(Comp) {
|
|
2870
3007
|
return function StudioIcon({ size = 20, strokeWidth = 2, colorToken = "floatingContent", ...rest }) {
|
|
2871
3008
|
const color = useResolvedIconColor(colorToken);
|
|
2872
|
-
return /* @__PURE__ */
|
|
3009
|
+
return /* @__PURE__ */ jsx16(Comp, { size, strokeWidth, color, ...rest });
|
|
2873
3010
|
};
|
|
2874
3011
|
}
|
|
2875
3012
|
var IconHome = makeIcon(Home);
|
|
@@ -2885,16 +3022,16 @@ var IconArrowDown = makeIcon(ArrowDown);
|
|
|
2885
3022
|
var IconApprove = makeIcon(Check2);
|
|
2886
3023
|
|
|
2887
3024
|
// src/components/chat/ChatComposer.tsx
|
|
2888
|
-
import { jsx as
|
|
3025
|
+
import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2889
3026
|
var THUMBNAIL_HEIGHT = 90;
|
|
2890
3027
|
function AspectRatioThumbnail({
|
|
2891
3028
|
uri,
|
|
2892
3029
|
onRemove,
|
|
2893
3030
|
renderRemoveIcon
|
|
2894
3031
|
}) {
|
|
2895
|
-
const [aspectRatio, setAspectRatio] =
|
|
3032
|
+
const [aspectRatio, setAspectRatio] = React18.useState(1);
|
|
2896
3033
|
return /* @__PURE__ */ jsxs8(View11, { style: { height: THUMBNAIL_HEIGHT, aspectRatio, position: "relative" }, children: [
|
|
2897
|
-
/* @__PURE__ */
|
|
3034
|
+
/* @__PURE__ */ jsx17(View11, { style: { flex: 1, borderRadius: 8, overflow: "hidden" }, children: /* @__PURE__ */ jsx17(
|
|
2898
3035
|
Image,
|
|
2899
3036
|
{
|
|
2900
3037
|
source: { uri },
|
|
@@ -2907,7 +3044,7 @@ function AspectRatioThumbnail({
|
|
|
2907
3044
|
}
|
|
2908
3045
|
}
|
|
2909
3046
|
) }),
|
|
2910
|
-
onRemove ? /* @__PURE__ */
|
|
3047
|
+
onRemove ? /* @__PURE__ */ jsx17(
|
|
2911
3048
|
Pressable4,
|
|
2912
3049
|
{
|
|
2913
3050
|
style: {
|
|
@@ -2924,7 +3061,7 @@ function AspectRatioThumbnail({
|
|
|
2924
3061
|
},
|
|
2925
3062
|
onPress: onRemove,
|
|
2926
3063
|
hitSlop: 10,
|
|
2927
|
-
children: renderRemoveIcon ? renderRemoveIcon() : /* @__PURE__ */
|
|
3064
|
+
children: renderRemoveIcon ? renderRemoveIcon() : /* @__PURE__ */ jsx17(IconClose, { size: 12, colorToken: "onPrimary" })
|
|
2928
3065
|
}
|
|
2929
3066
|
) : null
|
|
2930
3067
|
] });
|
|
@@ -2949,19 +3086,19 @@ function ChatComposer({
|
|
|
2949
3086
|
style
|
|
2950
3087
|
}) {
|
|
2951
3088
|
const theme = useTheme();
|
|
2952
|
-
const [internal, setInternal] =
|
|
3089
|
+
const [internal, setInternal] = React18.useState("");
|
|
2953
3090
|
const text = value ?? internal;
|
|
2954
3091
|
const setText = onChangeValue ?? setInternal;
|
|
2955
3092
|
const hasAttachments = attachments.length > 0;
|
|
2956
3093
|
const hasText = text.trim().length > 0;
|
|
2957
3094
|
const composerMinHeight = hasAttachments ? THUMBNAIL_HEIGHT + 44 + 24 : 44;
|
|
2958
3095
|
const isButtonDisabled = sending || disabled || sendDisabled;
|
|
2959
|
-
const maxInputHeight =
|
|
2960
|
-
const shakeAnim =
|
|
2961
|
-
const [sendPressed, setSendPressed] =
|
|
2962
|
-
const inputRef =
|
|
2963
|
-
const prevAutoFocusRef =
|
|
2964
|
-
|
|
3096
|
+
const maxInputHeight = React18.useMemo(() => Dimensions.get("window").height * 0.5, []);
|
|
3097
|
+
const shakeAnim = React18.useRef(new Animated5.Value(0)).current;
|
|
3098
|
+
const [sendPressed, setSendPressed] = React18.useState(false);
|
|
3099
|
+
const inputRef = React18.useRef(null);
|
|
3100
|
+
const prevAutoFocusRef = React18.useRef(false);
|
|
3101
|
+
React18.useEffect(() => {
|
|
2965
3102
|
const shouldFocus = autoFocus && !prevAutoFocusRef.current && !disabled && !sending;
|
|
2966
3103
|
prevAutoFocusRef.current = autoFocus;
|
|
2967
3104
|
if (!shouldFocus) return;
|
|
@@ -2971,7 +3108,7 @@ function ChatComposer({
|
|
|
2971
3108
|
}, 75);
|
|
2972
3109
|
return () => clearTimeout(t);
|
|
2973
3110
|
}, [autoFocus, disabled, sending]);
|
|
2974
|
-
const triggerShake =
|
|
3111
|
+
const triggerShake = React18.useCallback(() => {
|
|
2975
3112
|
shakeAnim.setValue(0);
|
|
2976
3113
|
Animated5.sequence([
|
|
2977
3114
|
Animated5.timing(shakeAnim, { toValue: 10, duration: 50, useNativeDriver: true }),
|
|
@@ -2981,7 +3118,7 @@ function ChatComposer({
|
|
|
2981
3118
|
Animated5.timing(shakeAnim, { toValue: 0, duration: 50, useNativeDriver: true })
|
|
2982
3119
|
]).start();
|
|
2983
3120
|
}, [shakeAnim]);
|
|
2984
|
-
const handleSend =
|
|
3121
|
+
const handleSend = React18.useCallback(async () => {
|
|
2985
3122
|
if (isButtonDisabled) return;
|
|
2986
3123
|
if (!hasText) {
|
|
2987
3124
|
triggerShake();
|
|
@@ -2993,14 +3130,15 @@ function ChatComposer({
|
|
|
2993
3130
|
}, [attachments, hasText, isButtonDisabled, onSend, setText, text, triggerShake]);
|
|
2994
3131
|
const textareaBgColor = theme.scheme === "dark" ? "#18181B" : "#F6F6F6";
|
|
2995
3132
|
const placeholderTextColor = theme.scheme === "dark" ? "#A1A1AA" : "#71717A";
|
|
2996
|
-
|
|
3133
|
+
const sendBg = withAlpha(theme.colors.primary, isButtonDisabled ? 0.6 : sendPressed ? 0.9 : 1);
|
|
3134
|
+
return /* @__PURE__ */ jsx17(
|
|
2997
3135
|
View11,
|
|
2998
3136
|
{
|
|
2999
3137
|
style: [{ paddingHorizontal: 16, paddingBottom: 12, paddingTop: 8 }, style],
|
|
3000
3138
|
onLayout: (e) => onLayout == null ? void 0 : onLayout({ height: e.nativeEvent.layout.height }),
|
|
3001
3139
|
children: /* @__PURE__ */ jsxs8(View11, { style: { flexDirection: "row", alignItems: "flex-end", gap: 8 }, children: [
|
|
3002
|
-
/* @__PURE__ */
|
|
3003
|
-
|
|
3140
|
+
/* @__PURE__ */ jsx17(Animated5.View, { style: { flex: 1, transform: [{ translateX: shakeAnim }] }, children: /* @__PURE__ */ jsxs8(
|
|
3141
|
+
ResettableLiquidGlassView,
|
|
3004
3142
|
{
|
|
3005
3143
|
style: [
|
|
3006
3144
|
// LiquidGlassView doesn't reliably auto-size to children; ensure enough height for the
|
|
@@ -3019,7 +3157,7 @@ function ChatComposer({
|
|
|
3019
3157
|
keyboardShouldPersistTaps: "handled",
|
|
3020
3158
|
contentContainerStyle: { gap: 8, paddingHorizontal: 12, paddingTop: 12 },
|
|
3021
3159
|
children: [
|
|
3022
|
-
attachments.map((uri, index) => /* @__PURE__ */
|
|
3160
|
+
attachments.map((uri, index) => /* @__PURE__ */ jsx17(
|
|
3023
3161
|
AspectRatioThumbnail,
|
|
3024
3162
|
{
|
|
3025
3163
|
uri,
|
|
@@ -3028,7 +3166,7 @@ function ChatComposer({
|
|
|
3028
3166
|
},
|
|
3029
3167
|
`attachment-${index}`
|
|
3030
3168
|
)),
|
|
3031
|
-
onAddAttachment ? renderAddAttachment ? renderAddAttachment() : /* @__PURE__ */
|
|
3169
|
+
onAddAttachment ? renderAddAttachment ? renderAddAttachment() : /* @__PURE__ */ jsx17(
|
|
3032
3170
|
Pressable4,
|
|
3033
3171
|
{
|
|
3034
3172
|
style: {
|
|
@@ -3043,13 +3181,13 @@ function ChatComposer({
|
|
|
3043
3181
|
backgroundColor: "rgba(255, 255, 255, 0.05)"
|
|
3044
3182
|
},
|
|
3045
3183
|
onPress: onAddAttachment,
|
|
3046
|
-
children: /* @__PURE__ */
|
|
3184
|
+
children: /* @__PURE__ */ jsx17(Plus, { size: 24, color: "rgba(255, 255, 255, 0.5)" })
|
|
3047
3185
|
}
|
|
3048
3186
|
) : null
|
|
3049
3187
|
]
|
|
3050
3188
|
}
|
|
3051
3189
|
) : null,
|
|
3052
|
-
/* @__PURE__ */
|
|
3190
|
+
/* @__PURE__ */ jsx17(
|
|
3053
3191
|
MultilineTextInput,
|
|
3054
3192
|
{
|
|
3055
3193
|
ref: inputRef,
|
|
@@ -3074,13 +3212,13 @@ function ChatComposer({
|
|
|
3074
3212
|
]
|
|
3075
3213
|
}
|
|
3076
3214
|
) }),
|
|
3077
|
-
/* @__PURE__ */
|
|
3078
|
-
|
|
3215
|
+
/* @__PURE__ */ jsx17(
|
|
3216
|
+
ResettableLiquidGlassView,
|
|
3079
3217
|
{
|
|
3080
3218
|
style: [{ borderRadius: 100 }, !isLiquidGlassSupported3 && { backgroundColor: textareaBgColor }],
|
|
3081
3219
|
interactive: true,
|
|
3082
3220
|
effect: "clear",
|
|
3083
|
-
children: /* @__PURE__ */
|
|
3221
|
+
children: /* @__PURE__ */ jsx17(
|
|
3084
3222
|
View11,
|
|
3085
3223
|
{
|
|
3086
3224
|
style: {
|
|
@@ -3088,10 +3226,9 @@ function ChatComposer({
|
|
|
3088
3226
|
height: 44,
|
|
3089
3227
|
borderRadius: 22,
|
|
3090
3228
|
overflow: "hidden",
|
|
3091
|
-
backgroundColor:
|
|
3092
|
-
opacity: isButtonDisabled ? 0.6 : sendPressed ? 0.9 : 1
|
|
3229
|
+
backgroundColor: sendBg
|
|
3093
3230
|
},
|
|
3094
|
-
children: /* @__PURE__ */
|
|
3231
|
+
children: /* @__PURE__ */ jsx17(
|
|
3095
3232
|
Pressable4,
|
|
3096
3233
|
{
|
|
3097
3234
|
accessibilityRole: "button",
|
|
@@ -3101,7 +3238,7 @@ function ChatComposer({
|
|
|
3101
3238
|
onPressIn: () => setSendPressed(true),
|
|
3102
3239
|
onPressOut: () => setSendPressed(false),
|
|
3103
3240
|
style: { flex: 1, alignItems: "center", justifyContent: "center" },
|
|
3104
|
-
children: sending ? /* @__PURE__ */
|
|
3241
|
+
children: sending ? /* @__PURE__ */ jsx17(ActivityIndicator2, {}) : renderSendIcon ? renderSendIcon() : /* @__PURE__ */ jsx17(IconChevronRight, { size: 20, colorToken: "onPrimary" })
|
|
3105
3242
|
}
|
|
3106
3243
|
)
|
|
3107
3244
|
}
|
|
@@ -3114,12 +3251,12 @@ function ChatComposer({
|
|
|
3114
3251
|
}
|
|
3115
3252
|
|
|
3116
3253
|
// src/components/comments/CommentRow.tsx
|
|
3117
|
-
import * as
|
|
3254
|
+
import * as React19 from "react";
|
|
3118
3255
|
import { View as View13 } from "react-native";
|
|
3119
3256
|
|
|
3120
3257
|
// src/components/primitives/Avatar.tsx
|
|
3121
3258
|
import { Image as Image2, View as View12 } from "react-native";
|
|
3122
|
-
import { jsx as
|
|
3259
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
3123
3260
|
function initialsFrom(name) {
|
|
3124
3261
|
var _a, _b;
|
|
3125
3262
|
const trimmed = (name ?? "").trim();
|
|
@@ -3137,7 +3274,7 @@ function Avatar({
|
|
|
3137
3274
|
const theme = useTheme();
|
|
3138
3275
|
const radius = size / 2;
|
|
3139
3276
|
const fallbackBg = fallbackBackgroundColor ?? theme.colors.neutral;
|
|
3140
|
-
return /* @__PURE__ */
|
|
3277
|
+
return /* @__PURE__ */ jsx18(
|
|
3141
3278
|
View12,
|
|
3142
3279
|
{
|
|
3143
3280
|
style: [
|
|
@@ -3152,14 +3289,14 @@ function Avatar({
|
|
|
3152
3289
|
},
|
|
3153
3290
|
style
|
|
3154
3291
|
],
|
|
3155
|
-
children: uri ? /* @__PURE__ */
|
|
3292
|
+
children: uri ? /* @__PURE__ */ jsx18(
|
|
3156
3293
|
Image2,
|
|
3157
3294
|
{
|
|
3158
3295
|
source: { uri },
|
|
3159
3296
|
style: [{ width: size, height: size }, imageStyle],
|
|
3160
3297
|
resizeMode: "cover"
|
|
3161
3298
|
}
|
|
3162
|
-
) : /* @__PURE__ */
|
|
3299
|
+
) : /* @__PURE__ */ jsx18(Text, { variant: "caption", style: { color: theme.colors.onNeutral }, children: initialsFrom(name) })
|
|
3163
3300
|
}
|
|
3164
3301
|
);
|
|
3165
3302
|
}
|
|
@@ -3183,12 +3320,12 @@ function formatTimeAgo(iso) {
|
|
|
3183
3320
|
}
|
|
3184
3321
|
|
|
3185
3322
|
// src/components/comments/CommentRow.tsx
|
|
3186
|
-
import { jsx as
|
|
3323
|
+
import { jsx as jsx19, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
3187
3324
|
function CommentRow({ comment, showDivider }) {
|
|
3188
3325
|
const theme = useTheme();
|
|
3189
|
-
const [authorName, setAuthorName] =
|
|
3190
|
-
const [authorAvatar, setAuthorAvatar] =
|
|
3191
|
-
|
|
3326
|
+
const [authorName, setAuthorName] = React19.useState(null);
|
|
3327
|
+
const [authorAvatar, setAuthorAvatar] = React19.useState(null);
|
|
3328
|
+
React19.useEffect(() => {
|
|
3192
3329
|
let cancelled = false;
|
|
3193
3330
|
(async () => {
|
|
3194
3331
|
try {
|
|
@@ -3214,13 +3351,13 @@ function CommentRow({ comment, showDivider }) {
|
|
|
3214
3351
|
borderBottomColor: withAlpha(theme.colors.border, 0.5)
|
|
3215
3352
|
},
|
|
3216
3353
|
children: [
|
|
3217
|
-
/* @__PURE__ */
|
|
3354
|
+
/* @__PURE__ */ jsx19(Avatar, { size: 32, uri: authorAvatar, name: authorName ?? comment.authorId, style: { marginTop: 6 } }),
|
|
3218
3355
|
/* @__PURE__ */ jsxs9(View13, { style: { flex: 1, minWidth: 0, gap: 4 }, children: [
|
|
3219
3356
|
/* @__PURE__ */ jsxs9(View13, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.sm }, children: [
|
|
3220
|
-
/* @__PURE__ */
|
|
3221
|
-
/* @__PURE__ */
|
|
3357
|
+
/* @__PURE__ */ jsx19(Text, { style: { fontSize: 14, lineHeight: 18, fontWeight: theme.typography.fontWeight.bold, color: theme.colors.text }, children: authorName ?? "Unknown User" }),
|
|
3358
|
+
/* @__PURE__ */ jsx19(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, children: formatTimeAgo(comment.createdAt) })
|
|
3222
3359
|
] }),
|
|
3223
|
-
/* @__PURE__ */
|
|
3360
|
+
/* @__PURE__ */ jsx19(Text, { style: { fontSize: 14, lineHeight: 20, color: theme.colors.text }, children: comment.body ?? comment.description ?? "" })
|
|
3224
3361
|
] })
|
|
3225
3362
|
]
|
|
3226
3363
|
}
|
|
@@ -3228,7 +3365,7 @@ function CommentRow({ comment, showDivider }) {
|
|
|
3228
3365
|
}
|
|
3229
3366
|
|
|
3230
3367
|
// src/components/comments/useAppComments.ts
|
|
3231
|
-
import * as
|
|
3368
|
+
import * as React20 from "react";
|
|
3232
3369
|
|
|
3233
3370
|
// src/data/comments/remote.ts
|
|
3234
3371
|
var AppCommentsRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -3300,18 +3437,18 @@ var appCommentsRepository = new AppCommentsRepositoryImpl(appCommentsRemoteDataS
|
|
|
3300
3437
|
|
|
3301
3438
|
// src/components/comments/useAppComments.ts
|
|
3302
3439
|
function useAppComments(appId) {
|
|
3303
|
-
const [comments, setComments] =
|
|
3304
|
-
const [loading, setLoading] =
|
|
3305
|
-
const [sending, setSending] =
|
|
3306
|
-
const [error, setError] =
|
|
3307
|
-
const sortByCreatedAtAsc =
|
|
3440
|
+
const [comments, setComments] = React20.useState([]);
|
|
3441
|
+
const [loading, setLoading] = React20.useState(false);
|
|
3442
|
+
const [sending, setSending] = React20.useState(false);
|
|
3443
|
+
const [error, setError] = React20.useState(null);
|
|
3444
|
+
const sortByCreatedAtAsc = React20.useCallback((items) => {
|
|
3308
3445
|
return [...items].sort((a, b) => {
|
|
3309
3446
|
const at = a.createdAt ? new Date(a.createdAt).getTime() : 0;
|
|
3310
3447
|
const bt = b.createdAt ? new Date(b.createdAt).getTime() : 0;
|
|
3311
3448
|
return at - bt;
|
|
3312
3449
|
});
|
|
3313
3450
|
}, []);
|
|
3314
|
-
const refresh =
|
|
3451
|
+
const refresh = React20.useCallback(async () => {
|
|
3315
3452
|
if (!appId) {
|
|
3316
3453
|
setComments([]);
|
|
3317
3454
|
return;
|
|
@@ -3328,10 +3465,10 @@ function useAppComments(appId) {
|
|
|
3328
3465
|
setLoading(false);
|
|
3329
3466
|
}
|
|
3330
3467
|
}, [appId, sortByCreatedAtAsc]);
|
|
3331
|
-
|
|
3468
|
+
React20.useEffect(() => {
|
|
3332
3469
|
void refresh();
|
|
3333
3470
|
}, [refresh]);
|
|
3334
|
-
const create =
|
|
3471
|
+
const create = React20.useCallback(
|
|
3335
3472
|
async (text) => {
|
|
3336
3473
|
if (!appId) return;
|
|
3337
3474
|
const trimmed = text.trim();
|
|
@@ -3354,11 +3491,11 @@ function useAppComments(appId) {
|
|
|
3354
3491
|
}
|
|
3355
3492
|
|
|
3356
3493
|
// src/components/comments/useAppDetails.ts
|
|
3357
|
-
import * as
|
|
3494
|
+
import * as React21 from "react";
|
|
3358
3495
|
function useAppDetails(appId) {
|
|
3359
|
-
const [app, setApp] =
|
|
3360
|
-
const [loading, setLoading] =
|
|
3361
|
-
|
|
3496
|
+
const [app, setApp] = React21.useState(null);
|
|
3497
|
+
const [loading, setLoading] = React21.useState(false);
|
|
3498
|
+
React21.useEffect(() => {
|
|
3362
3499
|
if (!appId) {
|
|
3363
3500
|
setApp(null);
|
|
3364
3501
|
return;
|
|
@@ -3383,12 +3520,12 @@ function useAppDetails(appId) {
|
|
|
3383
3520
|
}
|
|
3384
3521
|
|
|
3385
3522
|
// src/components/comments/useIosKeyboardSnapFix.ts
|
|
3386
|
-
import * as
|
|
3387
|
-
import { Keyboard as Keyboard2, Platform as
|
|
3523
|
+
import * as React22 from "react";
|
|
3524
|
+
import { Keyboard as Keyboard2, Platform as Platform5 } from "react-native";
|
|
3388
3525
|
function useIosKeyboardSnapFix(sheetRef, options) {
|
|
3389
|
-
const [keyboardVisible, setKeyboardVisible] =
|
|
3390
|
-
|
|
3391
|
-
if (
|
|
3526
|
+
const [keyboardVisible, setKeyboardVisible] = React22.useState(false);
|
|
3527
|
+
React22.useEffect(() => {
|
|
3528
|
+
if (Platform5.OS !== "ios") return;
|
|
3392
3529
|
const show = Keyboard2.addListener("keyboardWillShow", () => setKeyboardVisible(true));
|
|
3393
3530
|
const hide = Keyboard2.addListener("keyboardWillHide", () => {
|
|
3394
3531
|
var _a;
|
|
@@ -3411,20 +3548,20 @@ function useIosKeyboardSnapFix(sheetRef, options) {
|
|
|
3411
3548
|
}
|
|
3412
3549
|
|
|
3413
3550
|
// src/components/comments/AppCommentsSheet.tsx
|
|
3414
|
-
import { jsx as
|
|
3551
|
+
import { jsx as jsx20, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3415
3552
|
function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
3416
3553
|
const theme = useTheme();
|
|
3417
3554
|
const insets = useSafeAreaInsets3();
|
|
3418
|
-
const sheetRef =
|
|
3419
|
-
const snapPoints =
|
|
3420
|
-
const currentIndexRef =
|
|
3555
|
+
const sheetRef = React23.useRef(null);
|
|
3556
|
+
const snapPoints = React23.useMemo(() => ["50%", "90%"], []);
|
|
3557
|
+
const currentIndexRef = React23.useRef(1);
|
|
3421
3558
|
const { comments, loading, sending, error, create, refresh } = useAppComments(appId);
|
|
3422
3559
|
const { app, loading: loadingApp } = useAppDetails(appId);
|
|
3423
3560
|
const { keyboardVisible } = useIosKeyboardSnapFix(sheetRef, {
|
|
3424
3561
|
getCurrentIndex: () => currentIndexRef.current,
|
|
3425
3562
|
targetIndex: 1
|
|
3426
3563
|
});
|
|
3427
|
-
|
|
3564
|
+
React23.useEffect(() => {
|
|
3428
3565
|
var _a, _b;
|
|
3429
3566
|
if (appId) {
|
|
3430
3567
|
(_a = sheetRef.current) == null ? void 0 : _a.present();
|
|
@@ -3433,29 +3570,29 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3433
3570
|
(_b = sheetRef.current) == null ? void 0 : _b.dismiss();
|
|
3434
3571
|
}
|
|
3435
3572
|
}, [appId, refresh]);
|
|
3436
|
-
|
|
3573
|
+
React23.useEffect(() => {
|
|
3437
3574
|
if (!appId) return;
|
|
3438
3575
|
onCountChange == null ? void 0 : onCountChange(comments.length);
|
|
3439
3576
|
}, [appId, comments.length, onCountChange]);
|
|
3440
|
-
const renderBackdrop =
|
|
3441
|
-
(props) => /* @__PURE__ */
|
|
3577
|
+
const renderBackdrop = React23.useCallback(
|
|
3578
|
+
(props) => /* @__PURE__ */ jsx20(BottomSheetBackdrop, { ...props, disappearsOnIndex: -1, appearsOnIndex: 0, opacity: 0.5 }),
|
|
3442
3579
|
[]
|
|
3443
3580
|
);
|
|
3444
|
-
const handleChange =
|
|
3581
|
+
const handleChange = React23.useCallback(
|
|
3445
3582
|
(index) => {
|
|
3446
3583
|
currentIndexRef.current = index;
|
|
3447
3584
|
if (index === -1) onClose();
|
|
3448
3585
|
},
|
|
3449
3586
|
[onClose]
|
|
3450
3587
|
);
|
|
3451
|
-
const handlePlay =
|
|
3588
|
+
const handlePlay = React23.useCallback(async () => {
|
|
3452
3589
|
var _a;
|
|
3453
3590
|
if (!appId) return;
|
|
3454
3591
|
(_a = sheetRef.current) == null ? void 0 : _a.dismiss();
|
|
3455
3592
|
await (onPlayApp == null ? void 0 : onPlayApp(appId));
|
|
3456
3593
|
onClose();
|
|
3457
3594
|
}, [appId, onClose, onPlayApp]);
|
|
3458
|
-
return /* @__PURE__ */
|
|
3595
|
+
return /* @__PURE__ */ jsx20(
|
|
3459
3596
|
BottomSheetModal,
|
|
3460
3597
|
{
|
|
3461
3598
|
ref: sheetRef,
|
|
@@ -3466,8 +3603,8 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3466
3603
|
onChange: handleChange,
|
|
3467
3604
|
backgroundStyle: {
|
|
3468
3605
|
backgroundColor: theme.scheme === "dark" ? "#0B080F" : "#FFFFFF",
|
|
3469
|
-
borderTopLeftRadius:
|
|
3470
|
-
borderTopRightRadius:
|
|
3606
|
+
borderTopLeftRadius: Platform6.OS === "ios" ? 39 : 16,
|
|
3607
|
+
borderTopRightRadius: Platform6.OS === "ios" ? 39 : 16
|
|
3471
3608
|
},
|
|
3472
3609
|
handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
|
|
3473
3610
|
keyboardBehavior: "interactive",
|
|
@@ -3488,7 +3625,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3488
3625
|
borderBottomColor: withAlpha(theme.colors.border, 0.1)
|
|
3489
3626
|
},
|
|
3490
3627
|
children: [
|
|
3491
|
-
/* @__PURE__ */
|
|
3628
|
+
/* @__PURE__ */ jsx20(
|
|
3492
3629
|
Text,
|
|
3493
3630
|
{
|
|
3494
3631
|
numberOfLines: 1,
|
|
@@ -3502,8 +3639,8 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3502
3639
|
children: loadingApp ? "Loading..." : (app == null ? void 0 : app.name) || "Comments"
|
|
3503
3640
|
}
|
|
3504
3641
|
),
|
|
3505
|
-
/* @__PURE__ */
|
|
3506
|
-
|
|
3642
|
+
/* @__PURE__ */ jsx20(
|
|
3643
|
+
ResettableLiquidGlassView,
|
|
3507
3644
|
{
|
|
3508
3645
|
style: [
|
|
3509
3646
|
{ borderRadius: 24 },
|
|
@@ -3511,19 +3648,18 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3511
3648
|
],
|
|
3512
3649
|
interactive: true,
|
|
3513
3650
|
effect: "clear",
|
|
3514
|
-
children: /* @__PURE__ */
|
|
3651
|
+
children: /* @__PURE__ */ jsx20(
|
|
3515
3652
|
View14,
|
|
3516
3653
|
{
|
|
3517
3654
|
style: {
|
|
3518
3655
|
width: 32,
|
|
3519
3656
|
height: 32,
|
|
3520
3657
|
borderRadius: 999,
|
|
3521
|
-
backgroundColor: theme.colors.primary,
|
|
3658
|
+
backgroundColor: withAlpha(theme.colors.primary, appId ? 1 : 0.5),
|
|
3522
3659
|
alignItems: "center",
|
|
3523
|
-
justifyContent: "center"
|
|
3524
|
-
opacity: appId ? 1 : 0.5
|
|
3660
|
+
justifyContent: "center"
|
|
3525
3661
|
},
|
|
3526
|
-
children: /* @__PURE__ */
|
|
3662
|
+
children: /* @__PURE__ */ jsx20(
|
|
3527
3663
|
Pressable5,
|
|
3528
3664
|
{
|
|
3529
3665
|
disabled: !appId,
|
|
@@ -3536,9 +3672,9 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3536
3672
|
alignItems: "center",
|
|
3537
3673
|
justifyContent: "center"
|
|
3538
3674
|
},
|
|
3539
|
-
pressed ? {
|
|
3675
|
+
pressed ? { transform: [{ scale: 0.96 }] } : null
|
|
3540
3676
|
],
|
|
3541
|
-
children: /* @__PURE__ */
|
|
3677
|
+
children: /* @__PURE__ */ jsx20(Play2, { size: 16, color: theme.colors.onPrimary })
|
|
3542
3678
|
}
|
|
3543
3679
|
)
|
|
3544
3680
|
}
|
|
@@ -3559,12 +3695,12 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3559
3695
|
},
|
|
3560
3696
|
keyboardShouldPersistTaps: "handled",
|
|
3561
3697
|
children: [
|
|
3562
|
-
loading && comments.length === 0 ? /* @__PURE__ */
|
|
3563
|
-
error ? /* @__PURE__ */
|
|
3698
|
+
loading && comments.length === 0 ? /* @__PURE__ */ jsx20(View14, { style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx20(ActivityIndicator3, {}) }) : comments.length === 0 ? /* @__PURE__ */ jsx20(View14, { style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx20(Text, { variant: "bodyMuted", style: { textAlign: "center" }, children: "No comments yet" }) }) : comments.map((c, idx) => /* @__PURE__ */ jsx20(CommentRow, { comment: c, showDivider: idx < comments.length - 1 }, c.id)),
|
|
3699
|
+
error ? /* @__PURE__ */ jsx20(Text, { variant: "captionMuted", style: { marginTop: theme.spacing.lg }, children: "Failed to load comments." }) : null
|
|
3564
3700
|
]
|
|
3565
3701
|
}
|
|
3566
3702
|
),
|
|
3567
|
-
/* @__PURE__ */
|
|
3703
|
+
/* @__PURE__ */ jsx20(
|
|
3568
3704
|
View14,
|
|
3569
3705
|
{
|
|
3570
3706
|
style: {
|
|
@@ -3574,12 +3710,12 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3574
3710
|
bottom: 0,
|
|
3575
3711
|
paddingHorizontal: theme.spacing.lg,
|
|
3576
3712
|
paddingTop: theme.spacing.sm,
|
|
3577
|
-
paddingBottom:
|
|
3713
|
+
paddingBottom: Platform6.OS === "ios" ? keyboardVisible ? theme.spacing.lg : insets.bottom : insets.bottom + 10,
|
|
3578
3714
|
borderTopWidth: 1,
|
|
3579
3715
|
borderTopColor: withAlpha(theme.colors.border, 0.1),
|
|
3580
3716
|
backgroundColor: withAlpha(theme.colors.background, 0.8)
|
|
3581
3717
|
},
|
|
3582
|
-
children: /* @__PURE__ */
|
|
3718
|
+
children: /* @__PURE__ */ jsx20(
|
|
3583
3719
|
ChatComposer,
|
|
3584
3720
|
{
|
|
3585
3721
|
placeholder: "Write a comment...",
|
|
@@ -3605,12 +3741,12 @@ import { ActivityIndicator as ActivityIndicator7, View as View33 } from "react-n
|
|
|
3605
3741
|
// src/components/preview/PreviewPage.tsx
|
|
3606
3742
|
import { View as View15 } from "react-native";
|
|
3607
3743
|
import { BottomSheetScrollView as BottomSheetScrollView2 } from "@gorhom/bottom-sheet";
|
|
3608
|
-
import { jsx as
|
|
3744
|
+
import { jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3609
3745
|
function PreviewPage({ header, children, contentStyle }) {
|
|
3610
3746
|
const theme = useTheme();
|
|
3611
3747
|
return /* @__PURE__ */ jsxs11(View15, { style: { flex: 1 }, children: [
|
|
3612
|
-
header ? /* @__PURE__ */
|
|
3613
|
-
/* @__PURE__ */
|
|
3748
|
+
header ? /* @__PURE__ */ jsx21(View15, { children: header }) : null,
|
|
3749
|
+
/* @__PURE__ */ jsx21(
|
|
3614
3750
|
BottomSheetScrollView2,
|
|
3615
3751
|
{
|
|
3616
3752
|
style: { flex: 1 },
|
|
@@ -3633,7 +3769,7 @@ import { View as View18 } from "react-native";
|
|
|
3633
3769
|
|
|
3634
3770
|
// src/components/studio-sheet/StudioSheetHeader.tsx
|
|
3635
3771
|
import { View as View16 } from "react-native";
|
|
3636
|
-
import { jsx as
|
|
3772
|
+
import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3637
3773
|
function StudioSheetHeader({ left, center, right, style }) {
|
|
3638
3774
|
const theme = useTheme();
|
|
3639
3775
|
return /* @__PURE__ */ jsxs12(
|
|
@@ -3650,19 +3786,19 @@ function StudioSheetHeader({ left, center, right, style }) {
|
|
|
3650
3786
|
style
|
|
3651
3787
|
],
|
|
3652
3788
|
children: [
|
|
3653
|
-
/* @__PURE__ */
|
|
3654
|
-
/* @__PURE__ */
|
|
3655
|
-
/* @__PURE__ */
|
|
3789
|
+
/* @__PURE__ */ jsx22(View16, { style: { flexDirection: "row", alignItems: "center" }, children: left }),
|
|
3790
|
+
/* @__PURE__ */ jsx22(View16, { style: { flex: 1, alignItems: "center" }, children: center }),
|
|
3791
|
+
/* @__PURE__ */ jsx22(View16, { style: { flexDirection: "row", alignItems: "center" }, children: right })
|
|
3656
3792
|
]
|
|
3657
3793
|
}
|
|
3658
3794
|
);
|
|
3659
3795
|
}
|
|
3660
3796
|
|
|
3661
3797
|
// src/components/studio-sheet/StudioSheetHeaderIconButton.tsx
|
|
3662
|
-
import * as
|
|
3798
|
+
import * as React24 from "react";
|
|
3663
3799
|
import { Pressable as Pressable6, View as View17 } from "react-native";
|
|
3664
|
-
import {
|
|
3665
|
-
import { jsx as
|
|
3800
|
+
import { isLiquidGlassSupported as isLiquidGlassSupported5 } from "@callstack/liquid-glass";
|
|
3801
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
3666
3802
|
function StudioSheetHeaderIconButton({
|
|
3667
3803
|
onPress,
|
|
3668
3804
|
disabled,
|
|
@@ -3674,18 +3810,19 @@ function StudioSheetHeaderIconButton({
|
|
|
3674
3810
|
}) {
|
|
3675
3811
|
const theme = useTheme();
|
|
3676
3812
|
const size = 44;
|
|
3677
|
-
const [pressed, setPressed] =
|
|
3813
|
+
const [pressed, setPressed] = React24.useState(false);
|
|
3678
3814
|
const solidBg = intent === "danger" ? theme.colors.danger : intent === "primary" ? theme.colors.primary : theme.colors.neutral;
|
|
3679
3815
|
const glassFallbackBg = theme.scheme === "dark" ? "#18181B" : "#F6F6F6";
|
|
3680
3816
|
const glassInnerBg = intent === "danger" ? theme.colors.danger : theme.colors.primary;
|
|
3681
3817
|
const resolvedOpacity = disabled ? 0.6 : pressed ? 0.9 : 1;
|
|
3682
|
-
|
|
3683
|
-
|
|
3818
|
+
const glassBg = withAlpha(glassInnerBg, resolvedOpacity);
|
|
3819
|
+
return /* @__PURE__ */ jsx23(View17, { style, children: appearance === "glass" ? /* @__PURE__ */ jsx23(
|
|
3820
|
+
ResettableLiquidGlassView,
|
|
3684
3821
|
{
|
|
3685
3822
|
style: [{ borderRadius: 100 }, !isLiquidGlassSupported5 && { backgroundColor: glassFallbackBg }],
|
|
3686
3823
|
interactive: true,
|
|
3687
3824
|
effect: "clear",
|
|
3688
|
-
children: /* @__PURE__ */
|
|
3825
|
+
children: /* @__PURE__ */ jsx23(
|
|
3689
3826
|
View17,
|
|
3690
3827
|
{
|
|
3691
3828
|
style: {
|
|
@@ -3694,10 +3831,9 @@ function StudioSheetHeaderIconButton({
|
|
|
3694
3831
|
borderRadius: 100,
|
|
3695
3832
|
alignItems: "center",
|
|
3696
3833
|
justifyContent: "center",
|
|
3697
|
-
backgroundColor:
|
|
3698
|
-
opacity: resolvedOpacity
|
|
3834
|
+
backgroundColor: glassBg
|
|
3699
3835
|
},
|
|
3700
|
-
children: /* @__PURE__ */
|
|
3836
|
+
children: /* @__PURE__ */ jsx23(
|
|
3701
3837
|
Pressable6,
|
|
3702
3838
|
{
|
|
3703
3839
|
accessibilityRole: "button",
|
|
@@ -3716,7 +3852,7 @@ function StudioSheetHeaderIconButton({
|
|
|
3716
3852
|
}
|
|
3717
3853
|
)
|
|
3718
3854
|
}
|
|
3719
|
-
) : /* @__PURE__ */
|
|
3855
|
+
) : /* @__PURE__ */ jsx23(
|
|
3720
3856
|
View17,
|
|
3721
3857
|
{
|
|
3722
3858
|
style: {
|
|
@@ -3728,7 +3864,7 @@ function StudioSheetHeaderIconButton({
|
|
|
3728
3864
|
backgroundColor: solidBg,
|
|
3729
3865
|
opacity: resolvedOpacity
|
|
3730
3866
|
},
|
|
3731
|
-
children: /* @__PURE__ */
|
|
3867
|
+
children: /* @__PURE__ */ jsx23(
|
|
3732
3868
|
Pressable6,
|
|
3733
3869
|
{
|
|
3734
3870
|
accessibilityRole: "button",
|
|
@@ -3749,15 +3885,15 @@ function StudioSheetHeaderIconButton({
|
|
|
3749
3885
|
}
|
|
3750
3886
|
|
|
3751
3887
|
// src/studio/ui/preview-panel/PreviewPanelHeader.tsx
|
|
3752
|
-
import { jsx as
|
|
3888
|
+
import { jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3753
3889
|
function PreviewPanelHeader({ isOwner, onClose, onNavigateHome, onGoToChat }) {
|
|
3754
|
-
return /* @__PURE__ */
|
|
3890
|
+
return /* @__PURE__ */ jsx24(
|
|
3755
3891
|
StudioSheetHeader,
|
|
3756
3892
|
{
|
|
3757
|
-
left: onNavigateHome ? /* @__PURE__ */
|
|
3893
|
+
left: onNavigateHome ? /* @__PURE__ */ jsx24(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", appearance: "glass", intent: "primary", children: /* @__PURE__ */ jsx24(IconHome, { size: 20, colorToken: "onPrimary" }) }) : null,
|
|
3758
3894
|
center: null,
|
|
3759
3895
|
right: /* @__PURE__ */ jsxs13(View18, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
3760
|
-
isOwner ? /* @__PURE__ */
|
|
3896
|
+
isOwner ? /* @__PURE__ */ jsx24(
|
|
3761
3897
|
StudioSheetHeaderIconButton,
|
|
3762
3898
|
{
|
|
3763
3899
|
onPress: onGoToChat,
|
|
@@ -3765,10 +3901,10 @@ function PreviewPanelHeader({ isOwner, onClose, onNavigateHome, onGoToChat }) {
|
|
|
3765
3901
|
intent: "primary",
|
|
3766
3902
|
appearance: "glass",
|
|
3767
3903
|
style: { marginRight: 8 },
|
|
3768
|
-
children: /* @__PURE__ */
|
|
3904
|
+
children: /* @__PURE__ */ jsx24(IconChat, { size: 20, colorToken: "onPrimary" })
|
|
3769
3905
|
}
|
|
3770
3906
|
) : null,
|
|
3771
|
-
/* @__PURE__ */
|
|
3907
|
+
/* @__PURE__ */ jsx24(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", appearance: "glass", intent: "primary", children: /* @__PURE__ */ jsx24(IconClose, { size: 20, colorToken: "onPrimary" }) })
|
|
3772
3908
|
] })
|
|
3773
3909
|
}
|
|
3774
3910
|
);
|
|
@@ -3779,7 +3915,7 @@ import { View as View20 } from "react-native";
|
|
|
3779
3915
|
|
|
3780
3916
|
// src/components/primitives/Surface.tsx
|
|
3781
3917
|
import { View as View19 } from "react-native";
|
|
3782
|
-
import { jsx as
|
|
3918
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
3783
3919
|
function backgroundFor(variant, theme) {
|
|
3784
3920
|
const { colors } = theme;
|
|
3785
3921
|
switch (variant) {
|
|
@@ -3796,7 +3932,7 @@ function backgroundFor(variant, theme) {
|
|
|
3796
3932
|
}
|
|
3797
3933
|
function Surface({ variant = "surface", border = false, style, ...props }) {
|
|
3798
3934
|
const theme = useTheme();
|
|
3799
|
-
return /* @__PURE__ */
|
|
3935
|
+
return /* @__PURE__ */ jsx25(
|
|
3800
3936
|
View19,
|
|
3801
3937
|
{
|
|
3802
3938
|
...props,
|
|
@@ -3810,12 +3946,12 @@ function Surface({ variant = "surface", border = false, style, ...props }) {
|
|
|
3810
3946
|
}
|
|
3811
3947
|
|
|
3812
3948
|
// src/components/primitives/Card.tsx
|
|
3813
|
-
import { jsx as
|
|
3949
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
3814
3950
|
function Card({ variant = "surface", padded = true, border = true, style, ...props }) {
|
|
3815
3951
|
const theme = useTheme();
|
|
3816
3952
|
const radius = theme.radii.lg;
|
|
3817
3953
|
const padding = padded ? theme.spacing.lg : 0;
|
|
3818
|
-
return /* @__PURE__ */
|
|
3954
|
+
return /* @__PURE__ */ jsx26(
|
|
3819
3955
|
Surface,
|
|
3820
3956
|
{
|
|
3821
3957
|
...props,
|
|
@@ -3827,7 +3963,7 @@ function Card({ variant = "surface", padded = true, border = true, style, ...pro
|
|
|
3827
3963
|
}
|
|
3828
3964
|
|
|
3829
3965
|
// src/components/preview/PreviewHeroCard.tsx
|
|
3830
|
-
import { jsx as
|
|
3966
|
+
import { jsx as jsx27, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3831
3967
|
function PreviewHeroCard({
|
|
3832
3968
|
aspectRatio = 4 / 3,
|
|
3833
3969
|
overlayTopLeft,
|
|
@@ -3838,7 +3974,7 @@ function PreviewHeroCard({
|
|
|
3838
3974
|
}) {
|
|
3839
3975
|
const theme = useTheme();
|
|
3840
3976
|
const radius = 16;
|
|
3841
|
-
return /* @__PURE__ */
|
|
3977
|
+
return /* @__PURE__ */ jsx27(
|
|
3842
3978
|
Card,
|
|
3843
3979
|
{
|
|
3844
3980
|
variant: "surfaceRaised",
|
|
@@ -3854,24 +3990,24 @@ function PreviewHeroCard({
|
|
|
3854
3990
|
style
|
|
3855
3991
|
],
|
|
3856
3992
|
children: /* @__PURE__ */ jsxs14(View20, { style: { flex: 1 }, children: [
|
|
3857
|
-
background ? /* @__PURE__ */
|
|
3858
|
-
image ? /* @__PURE__ */
|
|
3859
|
-
overlayTopLeft ? /* @__PURE__ */
|
|
3860
|
-
overlayBottom ? /* @__PURE__ */
|
|
3993
|
+
background ? /* @__PURE__ */ jsx27(View20, { style: { position: "absolute", inset: 0 }, children: background }) : null,
|
|
3994
|
+
image ? /* @__PURE__ */ jsx27(View20, { style: { position: "absolute", inset: 0 }, children: image }) : null,
|
|
3995
|
+
overlayTopLeft ? /* @__PURE__ */ jsx27(View20, { style: { position: "absolute", top: theme.spacing.sm, left: theme.spacing.sm, zIndex: 2 }, children: overlayTopLeft }) : null,
|
|
3996
|
+
overlayBottom ? /* @__PURE__ */ jsx27(View20, { style: { flex: 1, justifyContent: "flex-end" }, children: overlayBottom }) : null
|
|
3861
3997
|
] })
|
|
3862
3998
|
}
|
|
3863
3999
|
);
|
|
3864
4000
|
}
|
|
3865
4001
|
|
|
3866
4002
|
// src/components/preview/PreviewPlaceholder.tsx
|
|
3867
|
-
import * as
|
|
4003
|
+
import * as React25 from "react";
|
|
3868
4004
|
import { Animated as Animated6 } from "react-native";
|
|
3869
4005
|
import { LinearGradient as LinearGradient2 } from "expo-linear-gradient";
|
|
3870
|
-
import { Fragment as Fragment3, jsx as
|
|
4006
|
+
import { Fragment as Fragment3, jsx as jsx28, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3871
4007
|
function PreviewPlaceholder({ visible, style }) {
|
|
3872
4008
|
if (!visible) return null;
|
|
3873
|
-
const opacityAnim =
|
|
3874
|
-
|
|
4009
|
+
const opacityAnim = React25.useRef(new Animated6.Value(0)).current;
|
|
4010
|
+
React25.useEffect(() => {
|
|
3875
4011
|
if (!visible) return;
|
|
3876
4012
|
const animation = Animated6.loop(
|
|
3877
4013
|
Animated6.sequence([
|
|
@@ -3889,7 +4025,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3889
4025
|
const opacity3 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 1, 0] });
|
|
3890
4026
|
const opacity4 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 0, 1] });
|
|
3891
4027
|
return /* @__PURE__ */ jsxs15(Fragment3, { children: [
|
|
3892
|
-
/* @__PURE__ */
|
|
4028
|
+
/* @__PURE__ */ jsx28(Animated6.View, { style: [{ position: "absolute", inset: 0, opacity: opacity1 }, style], children: /* @__PURE__ */ jsx28(
|
|
3893
4029
|
LinearGradient2,
|
|
3894
4030
|
{
|
|
3895
4031
|
colors: ["rgba(98, 0, 238, 0.45)", "rgba(168, 85, 247, 0.35)"],
|
|
@@ -3898,7 +4034,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3898
4034
|
style: { width: "100%", height: "100%" }
|
|
3899
4035
|
}
|
|
3900
4036
|
) }),
|
|
3901
|
-
/* @__PURE__ */
|
|
4037
|
+
/* @__PURE__ */ jsx28(Animated6.View, { style: [{ position: "absolute", inset: 0, opacity: opacity2 }, style], children: /* @__PURE__ */ jsx28(
|
|
3902
4038
|
LinearGradient2,
|
|
3903
4039
|
{
|
|
3904
4040
|
colors: ["rgba(168, 85, 247, 0.45)", "rgba(139, 92, 246, 0.35)"],
|
|
@@ -3907,7 +4043,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3907
4043
|
style: { width: "100%", height: "100%" }
|
|
3908
4044
|
}
|
|
3909
4045
|
) }),
|
|
3910
|
-
/* @__PURE__ */
|
|
4046
|
+
/* @__PURE__ */ jsx28(Animated6.View, { style: [{ position: "absolute", inset: 0, opacity: opacity3 }, style], children: /* @__PURE__ */ jsx28(
|
|
3911
4047
|
LinearGradient2,
|
|
3912
4048
|
{
|
|
3913
4049
|
colors: ["rgba(139, 92, 246, 0.45)", "rgba(126, 34, 206, 0.35)"],
|
|
@@ -3916,7 +4052,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3916
4052
|
style: { width: "100%", height: "100%" }
|
|
3917
4053
|
}
|
|
3918
4054
|
) }),
|
|
3919
|
-
/* @__PURE__ */
|
|
4055
|
+
/* @__PURE__ */ jsx28(Animated6.View, { style: [{ position: "absolute", inset: 0, opacity: opacity4 }, style], children: /* @__PURE__ */ jsx28(
|
|
3920
4056
|
LinearGradient2,
|
|
3921
4057
|
{
|
|
3922
4058
|
colors: ["rgba(126, 34, 206, 0.45)", "rgba(98, 0, 238, 0.35)"],
|
|
@@ -3930,10 +4066,10 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3930
4066
|
|
|
3931
4067
|
// src/components/preview/PreviewImage.tsx
|
|
3932
4068
|
import { Image as Image3 } from "react-native";
|
|
3933
|
-
import { jsx as
|
|
4069
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
3934
4070
|
function PreviewImage({ uri, onLoad, style }) {
|
|
3935
4071
|
if (!uri) return null;
|
|
3936
|
-
return /* @__PURE__ */
|
|
4072
|
+
return /* @__PURE__ */ jsx29(
|
|
3937
4073
|
Image3,
|
|
3938
4074
|
{
|
|
3939
4075
|
source: { uri },
|
|
@@ -3946,14 +4082,14 @@ function PreviewImage({ uri, onLoad, style }) {
|
|
|
3946
4082
|
|
|
3947
4083
|
// src/components/preview/StatsBar.tsx
|
|
3948
4084
|
import { Pressable as Pressable7, View as View21 } from "react-native";
|
|
3949
|
-
import {
|
|
4085
|
+
import { isLiquidGlassSupported as isLiquidGlassSupported6 } from "@callstack/liquid-glass";
|
|
3950
4086
|
import { Heart, MessageCircle } from "lucide-react-native";
|
|
3951
4087
|
|
|
3952
4088
|
// src/components/icons/MergeIcon.tsx
|
|
3953
4089
|
import Svg2, { Path as Path2 } from "react-native-svg";
|
|
3954
|
-
import { jsx as
|
|
4090
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
3955
4091
|
function MergeIcon({ color = "currentColor", width = 24, height = 24, ...props }) {
|
|
3956
|
-
return /* @__PURE__ */
|
|
4092
|
+
return /* @__PURE__ */ jsx30(Svg2, { viewBox: "0 0 486 486", width, height, ...props, children: /* @__PURE__ */ jsx30(
|
|
3957
4093
|
Path2,
|
|
3958
4094
|
{
|
|
3959
4095
|
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",
|
|
@@ -3963,7 +4099,7 @@ function MergeIcon({ color = "currentColor", width = 24, height = 24, ...props }
|
|
|
3963
4099
|
}
|
|
3964
4100
|
|
|
3965
4101
|
// src/components/preview/StatsBar.tsx
|
|
3966
|
-
import { jsx as
|
|
4102
|
+
import { jsx as jsx31, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3967
4103
|
function StatsBar({
|
|
3968
4104
|
likeCount,
|
|
3969
4105
|
commentCount,
|
|
@@ -3977,7 +4113,7 @@ function StatsBar({
|
|
|
3977
4113
|
}) {
|
|
3978
4114
|
const theme = useTheme();
|
|
3979
4115
|
const statsBgColor = theme.scheme === "dark" ? "rgba(24, 24, 27, 0.5)" : "rgba(255, 255, 255, 0.5)";
|
|
3980
|
-
return /* @__PURE__ */
|
|
4116
|
+
return /* @__PURE__ */ jsx31(
|
|
3981
4117
|
View21,
|
|
3982
4118
|
{
|
|
3983
4119
|
style: [
|
|
@@ -3985,8 +4121,8 @@ function StatsBar({
|
|
|
3985
4121
|
centered && { alignItems: "center" },
|
|
3986
4122
|
style
|
|
3987
4123
|
],
|
|
3988
|
-
children: /* @__PURE__ */
|
|
3989
|
-
|
|
4124
|
+
children: /* @__PURE__ */ jsx31(
|
|
4125
|
+
ResettableLiquidGlassView,
|
|
3990
4126
|
{
|
|
3991
4127
|
style: [
|
|
3992
4128
|
{ borderRadius: 100, overflow: "hidden" },
|
|
@@ -3995,7 +4131,7 @@ function StatsBar({
|
|
|
3995
4131
|
],
|
|
3996
4132
|
effect: "clear",
|
|
3997
4133
|
children: /* @__PURE__ */ jsxs16(View21, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16 }, children: [
|
|
3998
|
-
/* @__PURE__ */
|
|
4134
|
+
/* @__PURE__ */ jsx31(
|
|
3999
4135
|
Pressable7,
|
|
4000
4136
|
{
|
|
4001
4137
|
disabled: !onPressLike,
|
|
@@ -4003,7 +4139,7 @@ function StatsBar({
|
|
|
4003
4139
|
hitSlop: 8,
|
|
4004
4140
|
style: { paddingVertical: 8 },
|
|
4005
4141
|
children: /* @__PURE__ */ jsxs16(View21, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4006
|
-
/* @__PURE__ */
|
|
4142
|
+
/* @__PURE__ */ jsx31(
|
|
4007
4143
|
Heart,
|
|
4008
4144
|
{
|
|
4009
4145
|
size: 16,
|
|
@@ -4012,8 +4148,8 @@ function StatsBar({
|
|
|
4012
4148
|
fill: isLiked ? theme.colors.danger : "transparent"
|
|
4013
4149
|
}
|
|
4014
4150
|
),
|
|
4015
|
-
/* @__PURE__ */
|
|
4016
|
-
/* @__PURE__ */
|
|
4151
|
+
/* @__PURE__ */ jsx31(View21, { style: { width: 4 } }),
|
|
4152
|
+
/* @__PURE__ */ jsx31(
|
|
4017
4153
|
Text,
|
|
4018
4154
|
{
|
|
4019
4155
|
variant: "caption",
|
|
@@ -4027,7 +4163,7 @@ function StatsBar({
|
|
|
4027
4163
|
] })
|
|
4028
4164
|
}
|
|
4029
4165
|
),
|
|
4030
|
-
/* @__PURE__ */
|
|
4166
|
+
/* @__PURE__ */ jsx31(
|
|
4031
4167
|
Pressable7,
|
|
4032
4168
|
{
|
|
4033
4169
|
disabled: !onPressComments,
|
|
@@ -4035,16 +4171,16 @@ function StatsBar({
|
|
|
4035
4171
|
hitSlop: 8,
|
|
4036
4172
|
style: { paddingVertical: 8 },
|
|
4037
4173
|
children: /* @__PURE__ */ jsxs16(View21, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4038
|
-
/* @__PURE__ */
|
|
4039
|
-
/* @__PURE__ */
|
|
4040
|
-
/* @__PURE__ */
|
|
4174
|
+
/* @__PURE__ */ jsx31(MessageCircle, { size: 16, strokeWidth: 2.5, color: "#FFFFFF" }),
|
|
4175
|
+
/* @__PURE__ */ jsx31(View21, { style: { width: 4 } }),
|
|
4176
|
+
/* @__PURE__ */ jsx31(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: commentCount })
|
|
4041
4177
|
] })
|
|
4042
4178
|
}
|
|
4043
4179
|
),
|
|
4044
4180
|
/* @__PURE__ */ jsxs16(View21, { style: { flexDirection: "row", alignItems: "center", paddingVertical: 8 }, children: [
|
|
4045
|
-
/* @__PURE__ */
|
|
4046
|
-
/* @__PURE__ */
|
|
4047
|
-
/* @__PURE__ */
|
|
4181
|
+
/* @__PURE__ */ jsx31(View21, { style: { transform: [{ scaleY: -1 }] }, children: /* @__PURE__ */ jsx31(MergeIcon, { width: 14, height: 14, color: "#FFFFFF" }) }),
|
|
4182
|
+
/* @__PURE__ */ jsx31(View21, { style: { width: 4 } }),
|
|
4183
|
+
/* @__PURE__ */ jsx31(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: forkCount })
|
|
4048
4184
|
] })
|
|
4049
4185
|
] })
|
|
4050
4186
|
}
|
|
@@ -4077,7 +4213,7 @@ var APP_STATUS_LABEL = {
|
|
|
4077
4213
|
};
|
|
4078
4214
|
|
|
4079
4215
|
// src/components/preview/PreviewStatusBadge.tsx
|
|
4080
|
-
import { jsx as
|
|
4216
|
+
import { jsx as jsx32, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4081
4217
|
var STATUS_BG = {
|
|
4082
4218
|
ready: "#10B981",
|
|
4083
4219
|
// emerald-500
|
|
@@ -4118,15 +4254,15 @@ function PreviewStatusBadge({ status }) {
|
|
|
4118
4254
|
backgroundColor: STATUS_BG[status]
|
|
4119
4255
|
},
|
|
4120
4256
|
children: [
|
|
4121
|
-
/* @__PURE__ */
|
|
4122
|
-
/* @__PURE__ */
|
|
4257
|
+
/* @__PURE__ */ jsx32(IconComp, { size: 12, color: "#FFFFFF", style: { marginRight: 4 } }),
|
|
4258
|
+
/* @__PURE__ */ jsx32(Text, { style: { color: "#FFFFFF", fontSize: 11, lineHeight: 14 }, children: label })
|
|
4123
4259
|
]
|
|
4124
4260
|
}
|
|
4125
4261
|
);
|
|
4126
4262
|
}
|
|
4127
4263
|
|
|
4128
4264
|
// src/studio/ui/preview-panel/PreviewHeroSection.tsx
|
|
4129
|
-
import { jsx as
|
|
4265
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
4130
4266
|
function PreviewHeroSection({
|
|
4131
4267
|
appStatus,
|
|
4132
4268
|
showProcessing,
|
|
@@ -4135,13 +4271,13 @@ function PreviewHeroSection({
|
|
|
4135
4271
|
onImageLoad,
|
|
4136
4272
|
stats
|
|
4137
4273
|
}) {
|
|
4138
|
-
return /* @__PURE__ */
|
|
4274
|
+
return /* @__PURE__ */ jsx33(
|
|
4139
4275
|
PreviewHeroCard,
|
|
4140
4276
|
{
|
|
4141
|
-
overlayTopLeft: showProcessing ? /* @__PURE__ */
|
|
4142
|
-
background: /* @__PURE__ */
|
|
4143
|
-
image: /* @__PURE__ */
|
|
4144
|
-
overlayBottom: /* @__PURE__ */
|
|
4277
|
+
overlayTopLeft: showProcessing ? /* @__PURE__ */ jsx33(PreviewStatusBadge, { status: appStatus }) : null,
|
|
4278
|
+
background: /* @__PURE__ */ jsx33(PreviewPlaceholder, { visible: !imageLoaded }),
|
|
4279
|
+
image: /* @__PURE__ */ jsx33(PreviewImage, { uri: imageUrl, onLoad: onImageLoad }),
|
|
4280
|
+
overlayBottom: /* @__PURE__ */ jsx33(
|
|
4145
4281
|
StatsBar,
|
|
4146
4282
|
{
|
|
4147
4283
|
likeCount: stats.likeCount,
|
|
@@ -4164,7 +4300,7 @@ import { View as View24 } from "react-native";
|
|
|
4164
4300
|
|
|
4165
4301
|
// src/components/preview/PreviewMetaRow.tsx
|
|
4166
4302
|
import { View as View23 } from "react-native";
|
|
4167
|
-
import { jsx as
|
|
4303
|
+
import { jsx as jsx34, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4168
4304
|
function PreviewMetaRow({
|
|
4169
4305
|
avatarUri,
|
|
4170
4306
|
creatorName,
|
|
@@ -4177,9 +4313,9 @@ function PreviewMetaRow({
|
|
|
4177
4313
|
const theme = useTheme();
|
|
4178
4314
|
return /* @__PURE__ */ jsxs18(View23, { style: [{ alignSelf: "stretch" }, style], children: [
|
|
4179
4315
|
/* @__PURE__ */ jsxs18(View23, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4180
|
-
/* @__PURE__ */
|
|
4316
|
+
/* @__PURE__ */ jsx34(Avatar, { uri: avatarUri, name: creatorName, size: 24, style: { marginRight: theme.spacing.sm } }),
|
|
4181
4317
|
/* @__PURE__ */ jsxs18(View23, { style: { flexDirection: "row", alignItems: "center", flex: 1, minWidth: 0, marginRight: theme.spacing.sm }, children: [
|
|
4182
|
-
/* @__PURE__ */
|
|
4318
|
+
/* @__PURE__ */ jsx34(
|
|
4183
4319
|
Text,
|
|
4184
4320
|
{
|
|
4185
4321
|
numberOfLines: 1,
|
|
@@ -4193,11 +4329,11 @@ function PreviewMetaRow({
|
|
|
4193
4329
|
children: title
|
|
4194
4330
|
}
|
|
4195
4331
|
),
|
|
4196
|
-
tag ? /* @__PURE__ */
|
|
4332
|
+
tag ? /* @__PURE__ */ jsx34(View23, { style: { marginLeft: theme.spacing.sm }, children: tag }) : null
|
|
4197
4333
|
] }),
|
|
4198
|
-
rightMetric ? /* @__PURE__ */
|
|
4334
|
+
rightMetric ? /* @__PURE__ */ jsx34(View23, { children: rightMetric }) : null
|
|
4199
4335
|
] }),
|
|
4200
|
-
subtitle ? /* @__PURE__ */
|
|
4336
|
+
subtitle ? /* @__PURE__ */ jsx34(
|
|
4201
4337
|
Text,
|
|
4202
4338
|
{
|
|
4203
4339
|
numberOfLines: 2,
|
|
@@ -4240,18 +4376,18 @@ function statusDescription(status, statusError) {
|
|
|
4240
4376
|
}
|
|
4241
4377
|
|
|
4242
4378
|
// src/studio/ui/preview-panel/PreviewMetaSection.tsx
|
|
4243
|
-
import { jsx as
|
|
4379
|
+
import { jsx as jsx35, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4244
4380
|
function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
|
|
4245
4381
|
var _a;
|
|
4246
4382
|
const theme = useTheme();
|
|
4247
|
-
return /* @__PURE__ */
|
|
4383
|
+
return /* @__PURE__ */ jsx35(
|
|
4248
4384
|
PreviewMetaRow,
|
|
4249
4385
|
{
|
|
4250
4386
|
title: app.name,
|
|
4251
4387
|
subtitle: app.description,
|
|
4252
4388
|
avatarUri: (creator == null ? void 0 : creator.avatar) ?? null,
|
|
4253
4389
|
creatorName: (creator == null ? void 0 : creator.name) ?? null,
|
|
4254
|
-
tag: isOwner || app.forkedFromAppId ? /* @__PURE__ */
|
|
4390
|
+
tag: isOwner || app.forkedFromAppId ? /* @__PURE__ */ jsx35(View24, { style: { paddingHorizontal: 8, paddingVertical: 2, borderRadius: 999, backgroundColor: "#3700B3" }, children: /* @__PURE__ */ jsx35(Text, { variant: "caption", style: { color: "#fff", fontWeight: theme.typography.fontWeight.semibold }, children: app.forkedFromAppId ? "Remix" : "Owner" }) }) : null,
|
|
4255
4391
|
rightMetric: /* @__PURE__ */ jsxs19(
|
|
4256
4392
|
View24,
|
|
4257
4393
|
{
|
|
@@ -4264,7 +4400,7 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
|
|
|
4264
4400
|
backgroundColor: withAlpha(theme.colors.neutral, 0.3)
|
|
4265
4401
|
},
|
|
4266
4402
|
children: [
|
|
4267
|
-
/* @__PURE__ */
|
|
4403
|
+
/* @__PURE__ */ jsx35(
|
|
4268
4404
|
Text,
|
|
4269
4405
|
{
|
|
4270
4406
|
style: {
|
|
@@ -4277,7 +4413,7 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
|
|
|
4277
4413
|
children: formatCount(downloadsCount ?? ((_a = app.insights) == null ? void 0 : _a.totalDownloads) ?? 0)
|
|
4278
4414
|
}
|
|
4279
4415
|
),
|
|
4280
|
-
/* @__PURE__ */
|
|
4416
|
+
/* @__PURE__ */ jsx35(IconPlay, { size: 14, colorToken: "textMuted", fill: theme.colors.textMuted })
|
|
4281
4417
|
]
|
|
4282
4418
|
}
|
|
4283
4419
|
),
|
|
@@ -4291,7 +4427,7 @@ import { ActivityIndicator as ActivityIndicator4, View as View26 } from "react-n
|
|
|
4291
4427
|
|
|
4292
4428
|
// src/studio/ui/preview-panel/PressableCardRow.tsx
|
|
4293
4429
|
import { Pressable as Pressable8, View as View25 } from "react-native";
|
|
4294
|
-
import { jsx as
|
|
4430
|
+
import { jsx as jsx36, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4295
4431
|
function PressableCardRow({
|
|
4296
4432
|
accessibilityLabel,
|
|
4297
4433
|
onPress,
|
|
@@ -4302,7 +4438,7 @@ function PressableCardRow({
|
|
|
4302
4438
|
right,
|
|
4303
4439
|
style
|
|
4304
4440
|
}) {
|
|
4305
|
-
return /* @__PURE__ */
|
|
4441
|
+
return /* @__PURE__ */ jsx36(
|
|
4306
4442
|
Pressable8,
|
|
4307
4443
|
{
|
|
4308
4444
|
accessibilityRole: "button",
|
|
@@ -4310,23 +4446,23 @@ function PressableCardRow({
|
|
|
4310
4446
|
disabled,
|
|
4311
4447
|
onPress,
|
|
4312
4448
|
style: ({ pressed }) => ({ opacity: disabled ? 0.6 : pressed ? 0.85 : 1 }),
|
|
4313
|
-
children: /* @__PURE__ */
|
|
4449
|
+
children: /* @__PURE__ */ jsx36(Card, { padded: false, border: false, style, children: /* @__PURE__ */ jsxs20(View25, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4314
4450
|
left,
|
|
4315
4451
|
/* @__PURE__ */ jsxs20(View25, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4316
4452
|
title,
|
|
4317
4453
|
subtitle ? subtitle : null
|
|
4318
4454
|
] }),
|
|
4319
|
-
right ? /* @__PURE__ */
|
|
4455
|
+
right ? /* @__PURE__ */ jsx36(View25, { style: { marginLeft: 16 }, children: right }) : null
|
|
4320
4456
|
] }) })
|
|
4321
4457
|
}
|
|
4322
4458
|
);
|
|
4323
4459
|
}
|
|
4324
4460
|
|
|
4325
4461
|
// src/studio/ui/preview-panel/SectionTitle.tsx
|
|
4326
|
-
import { jsx as
|
|
4462
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
4327
4463
|
function SectionTitle({ children, marginTop }) {
|
|
4328
4464
|
const theme = useTheme();
|
|
4329
|
-
return /* @__PURE__ */
|
|
4465
|
+
return /* @__PURE__ */ jsx37(
|
|
4330
4466
|
Text,
|
|
4331
4467
|
{
|
|
4332
4468
|
style: {
|
|
@@ -4345,7 +4481,7 @@ function SectionTitle({ children, marginTop }) {
|
|
|
4345
4481
|
}
|
|
4346
4482
|
|
|
4347
4483
|
// src/studio/ui/preview-panel/PreviewCustomizeSection.tsx
|
|
4348
|
-
import { Fragment as Fragment4, jsx as
|
|
4484
|
+
import { Fragment as Fragment4, jsx as jsx38, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
4349
4485
|
function PreviewCustomizeSection({
|
|
4350
4486
|
app,
|
|
4351
4487
|
isOwner,
|
|
@@ -4356,7 +4492,7 @@ function PreviewCustomizeSection({
|
|
|
4356
4492
|
}) {
|
|
4357
4493
|
const theme = useTheme();
|
|
4358
4494
|
return /* @__PURE__ */ jsxs21(Fragment4, { children: [
|
|
4359
|
-
/* @__PURE__ */
|
|
4495
|
+
/* @__PURE__ */ jsx38(SectionTitle, { children: "Customize" }),
|
|
4360
4496
|
showProcessing ? /* @__PURE__ */ jsxs21(
|
|
4361
4497
|
View26,
|
|
4362
4498
|
{
|
|
@@ -4371,7 +4507,7 @@ function PreviewCustomizeSection({
|
|
|
4371
4507
|
marginBottom: theme.spacing.sm
|
|
4372
4508
|
},
|
|
4373
4509
|
children: [
|
|
4374
|
-
/* @__PURE__ */
|
|
4510
|
+
/* @__PURE__ */ jsx38(
|
|
4375
4511
|
View26,
|
|
4376
4512
|
{
|
|
4377
4513
|
style: {
|
|
@@ -4383,17 +4519,17 @@ function PreviewCustomizeSection({
|
|
|
4383
4519
|
backgroundColor: withAlpha(theme.colors.warning, 0.1),
|
|
4384
4520
|
marginRight: theme.spacing.lg
|
|
4385
4521
|
},
|
|
4386
|
-
children: /* @__PURE__ */
|
|
4522
|
+
children: /* @__PURE__ */ jsx38(ActivityIndicator4, { color: theme.colors.warning, size: "small" })
|
|
4387
4523
|
}
|
|
4388
4524
|
),
|
|
4389
4525
|
/* @__PURE__ */ jsxs21(View26, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4390
|
-
/* @__PURE__ */
|
|
4391
|
-
/* @__PURE__ */
|
|
4526
|
+
/* @__PURE__ */ jsx38(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: app.status === "error" ? "Error" : "Processing" }),
|
|
4527
|
+
/* @__PURE__ */ jsx38(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: statusDescription(app.status, app.statusError) })
|
|
4392
4528
|
] })
|
|
4393
4529
|
]
|
|
4394
4530
|
}
|
|
4395
4531
|
) : null,
|
|
4396
|
-
/* @__PURE__ */
|
|
4532
|
+
/* @__PURE__ */ jsx38(
|
|
4397
4533
|
PressableCardRow,
|
|
4398
4534
|
{
|
|
4399
4535
|
accessibilityLabel: isOwner ? "Edit app" : "Remix app",
|
|
@@ -4406,7 +4542,7 @@ function PreviewCustomizeSection({
|
|
|
4406
4542
|
borderColor: withAlpha(theme.colors.primary, 0.1),
|
|
4407
4543
|
marginBottom: theme.spacing.sm
|
|
4408
4544
|
},
|
|
4409
|
-
left: /* @__PURE__ */
|
|
4545
|
+
left: /* @__PURE__ */ jsx38(
|
|
4410
4546
|
View26,
|
|
4411
4547
|
{
|
|
4412
4548
|
style: {
|
|
@@ -4418,15 +4554,15 @@ function PreviewCustomizeSection({
|
|
|
4418
4554
|
backgroundColor: withAlpha(theme.colors.primary, 0.1),
|
|
4419
4555
|
marginRight: theme.spacing.lg
|
|
4420
4556
|
},
|
|
4421
|
-
children: /* @__PURE__ */
|
|
4557
|
+
children: /* @__PURE__ */ jsx38(IconChat, { size: 20, colorToken: "primary" })
|
|
4422
4558
|
}
|
|
4423
4559
|
),
|
|
4424
|
-
title: /* @__PURE__ */
|
|
4425
|
-
subtitle: /* @__PURE__ */
|
|
4426
|
-
right: /* @__PURE__ */
|
|
4560
|
+
title: /* @__PURE__ */ jsx38(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" }),
|
|
4561
|
+
subtitle: /* @__PURE__ */ jsx38(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" }),
|
|
4562
|
+
right: /* @__PURE__ */ jsx38(IconChevronRight, { size: 20, colorToken: "textMuted" })
|
|
4427
4563
|
}
|
|
4428
4564
|
),
|
|
4429
|
-
isOwner && onStartDraw ? /* @__PURE__ */
|
|
4565
|
+
isOwner && onStartDraw ? /* @__PURE__ */ jsx38(
|
|
4430
4566
|
PressableCardRow,
|
|
4431
4567
|
{
|
|
4432
4568
|
accessibilityLabel: "Draw changes",
|
|
@@ -4439,7 +4575,7 @@ function PreviewCustomizeSection({
|
|
|
4439
4575
|
borderColor: withAlpha(theme.colors.danger, 0.1),
|
|
4440
4576
|
marginBottom: theme.spacing.sm
|
|
4441
4577
|
},
|
|
4442
|
-
left: /* @__PURE__ */
|
|
4578
|
+
left: /* @__PURE__ */ jsx38(
|
|
4443
4579
|
View26,
|
|
4444
4580
|
{
|
|
4445
4581
|
style: {
|
|
@@ -4451,31 +4587,31 @@ function PreviewCustomizeSection({
|
|
|
4451
4587
|
backgroundColor: withAlpha(theme.colors.danger, 0.1),
|
|
4452
4588
|
marginRight: theme.spacing.lg
|
|
4453
4589
|
},
|
|
4454
|
-
children: /* @__PURE__ */
|
|
4590
|
+
children: /* @__PURE__ */ jsx38(IconDraw, { size: 20, colorToken: "danger" })
|
|
4455
4591
|
}
|
|
4456
4592
|
),
|
|
4457
|
-
title: /* @__PURE__ */
|
|
4458
|
-
subtitle: /* @__PURE__ */
|
|
4459
|
-
right: /* @__PURE__ */
|
|
4593
|
+
title: /* @__PURE__ */ jsx38(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Draw Changes" }),
|
|
4594
|
+
subtitle: /* @__PURE__ */ jsx38(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: "Annotate the app with drawings" }),
|
|
4595
|
+
right: /* @__PURE__ */ jsx38(IconChevronRight, { size: 20, colorToken: "textMuted" })
|
|
4460
4596
|
}
|
|
4461
4597
|
) : null
|
|
4462
4598
|
] });
|
|
4463
4599
|
}
|
|
4464
4600
|
|
|
4465
4601
|
// src/studio/ui/preview-panel/PreviewCollaborateSection.tsx
|
|
4466
|
-
import * as
|
|
4602
|
+
import * as React31 from "react";
|
|
4467
4603
|
import { ActivityIndicator as ActivityIndicator6, Alert, View as View32 } from "react-native";
|
|
4468
4604
|
import { Send as Send2 } from "lucide-react-native";
|
|
4469
4605
|
|
|
4470
4606
|
// src/components/merge-requests/MergeRequestStatusCard.tsx
|
|
4471
|
-
import * as
|
|
4607
|
+
import * as React27 from "react";
|
|
4472
4608
|
import { Animated as Animated7, Pressable as Pressable9, View as View28 } from "react-native";
|
|
4473
4609
|
import { Ban, Check as Check3, CheckCheck, ChevronDown as ChevronDown2 } from "lucide-react-native";
|
|
4474
4610
|
|
|
4475
4611
|
// src/components/primitives/MarkdownText.tsx
|
|
4476
|
-
import { Platform as
|
|
4612
|
+
import { Platform as Platform7, View as View27 } from "react-native";
|
|
4477
4613
|
import Markdown from "react-native-markdown-display";
|
|
4478
|
-
import { jsx as
|
|
4614
|
+
import { jsx as jsx39 } from "react/jsx-runtime";
|
|
4479
4615
|
function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
4480
4616
|
const theme = useTheme();
|
|
4481
4617
|
const isDark = theme.scheme === "dark";
|
|
@@ -4486,7 +4622,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
|
4486
4622
|
const codeTextColor = isDark ? "#FFFFFF" : theme.colors.text;
|
|
4487
4623
|
const paragraphBottom = variant === "mergeRequest" ? 8 : 6;
|
|
4488
4624
|
const baseLineHeight = variant === "mergeRequest" ? 22 : 20;
|
|
4489
|
-
return /* @__PURE__ */
|
|
4625
|
+
return /* @__PURE__ */ jsx39(View27, { style, children: /* @__PURE__ */ jsx39(
|
|
4490
4626
|
Markdown,
|
|
4491
4627
|
{
|
|
4492
4628
|
style: {
|
|
@@ -4499,7 +4635,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
|
4499
4635
|
paddingHorizontal: variant === "mergeRequest" ? 6 : 4,
|
|
4500
4636
|
paddingVertical: variant === "mergeRequest" ? 2 : 0,
|
|
4501
4637
|
borderRadius: variant === "mergeRequest" ? 6 : 4,
|
|
4502
|
-
fontFamily:
|
|
4638
|
+
fontFamily: Platform7.OS === "ios" ? "Menlo" : "monospace",
|
|
4503
4639
|
fontSize: 13
|
|
4504
4640
|
},
|
|
4505
4641
|
code_block: {
|
|
@@ -4550,11 +4686,11 @@ function toIsoString(input) {
|
|
|
4550
4686
|
}
|
|
4551
4687
|
|
|
4552
4688
|
// src/components/merge-requests/useControlledExpansion.ts
|
|
4553
|
-
import * as
|
|
4689
|
+
import * as React26 from "react";
|
|
4554
4690
|
function useControlledExpansion(props) {
|
|
4555
|
-
const [uncontrolled, setUncontrolled] =
|
|
4691
|
+
const [uncontrolled, setUncontrolled] = React26.useState(false);
|
|
4556
4692
|
const expanded = props.expanded ?? uncontrolled;
|
|
4557
|
-
const setExpanded =
|
|
4693
|
+
const setExpanded = React26.useCallback(
|
|
4558
4694
|
(next) => {
|
|
4559
4695
|
var _a;
|
|
4560
4696
|
(_a = props.onExpandedChange) == null ? void 0 : _a.call(props, next);
|
|
@@ -4566,7 +4702,7 @@ function useControlledExpansion(props) {
|
|
|
4566
4702
|
}
|
|
4567
4703
|
|
|
4568
4704
|
// src/components/merge-requests/MergeRequestStatusCard.tsx
|
|
4569
|
-
import { jsx as
|
|
4705
|
+
import { jsx as jsx40, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
4570
4706
|
function MergeRequestStatusCard({
|
|
4571
4707
|
mergeRequest,
|
|
4572
4708
|
expanded: expandedProp,
|
|
@@ -4579,8 +4715,8 @@ function MergeRequestStatusCard({
|
|
|
4579
4715
|
const isDark = theme.scheme === "dark";
|
|
4580
4716
|
const textColor = isDark ? "#FFFFFF" : "#000000";
|
|
4581
4717
|
const subTextColor = isDark ? "#A1A1AA" : "#71717A";
|
|
4582
|
-
const status =
|
|
4583
|
-
const { StatusIcon, iconColor, bgColor, statusText } =
|
|
4718
|
+
const status = React27.useMemo(() => getMergeRequestStatusDisplay(String(mergeRequest.status)), [mergeRequest.status]);
|
|
4719
|
+
const { StatusIcon, iconColor, bgColor, statusText } = React27.useMemo(() => {
|
|
4584
4720
|
switch (mergeRequest.status) {
|
|
4585
4721
|
case "approved":
|
|
4586
4722
|
case "merged":
|
|
@@ -4611,15 +4747,15 @@ function MergeRequestStatusCard({
|
|
|
4611
4747
|
const createdIso = toIsoString(mergeRequest.createdAt ?? null);
|
|
4612
4748
|
const headerTimeAgo = updatedIso ? formatTimeAgo(updatedIso) : "";
|
|
4613
4749
|
const createdTimeAgo = createdIso ? formatTimeAgo(createdIso) : "";
|
|
4614
|
-
const rotate =
|
|
4615
|
-
|
|
4750
|
+
const rotate = React27.useRef(new Animated7.Value(expanded ? 1 : 0)).current;
|
|
4751
|
+
React27.useEffect(() => {
|
|
4616
4752
|
Animated7.timing(rotate, {
|
|
4617
4753
|
toValue: expanded ? 1 : 0,
|
|
4618
4754
|
duration: 200,
|
|
4619
4755
|
useNativeDriver: true
|
|
4620
4756
|
}).start();
|
|
4621
4757
|
}, [expanded, rotate]);
|
|
4622
|
-
return /* @__PURE__ */
|
|
4758
|
+
return /* @__PURE__ */ jsx40(Pressable9, { onPress: () => setExpanded(!expanded), style: ({ pressed }) => [{ opacity: pressed ? 0.95 : 1 }], children: /* @__PURE__ */ jsxs22(
|
|
4623
4759
|
Card,
|
|
4624
4760
|
{
|
|
4625
4761
|
padded: false,
|
|
@@ -4633,10 +4769,10 @@ function MergeRequestStatusCard({
|
|
|
4633
4769
|
],
|
|
4634
4770
|
children: [
|
|
4635
4771
|
/* @__PURE__ */ jsxs22(View28, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.lg }, children: [
|
|
4636
|
-
/* @__PURE__ */
|
|
4772
|
+
/* @__PURE__ */ jsx40(View28, { style: { width: 40, height: 40, borderRadius: 999, alignItems: "center", justifyContent: "center", backgroundColor: bgColor }, children: /* @__PURE__ */ jsx40(StatusIcon, { size: 20, color: iconColor }) }),
|
|
4637
4773
|
/* @__PURE__ */ jsxs22(View28, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4638
4774
|
/* @__PURE__ */ jsxs22(View28, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
4639
|
-
/* @__PURE__ */
|
|
4775
|
+
/* @__PURE__ */ jsx40(
|
|
4640
4776
|
Text,
|
|
4641
4777
|
{
|
|
4642
4778
|
style: {
|
|
@@ -4650,11 +4786,11 @@ function MergeRequestStatusCard({
|
|
|
4650
4786
|
children: statusText
|
|
4651
4787
|
}
|
|
4652
4788
|
),
|
|
4653
|
-
headerTimeAgo ? /* @__PURE__ */
|
|
4789
|
+
headerTimeAgo ? /* @__PURE__ */ jsx40(Text, { style: { fontSize: 10, lineHeight: 14, marginLeft: theme.spacing.sm, color: withAlpha(theme.colors.textMuted, 0.6) }, children: headerTimeAgo }) : null
|
|
4654
4790
|
] }),
|
|
4655
|
-
/* @__PURE__ */
|
|
4791
|
+
/* @__PURE__ */ jsx40(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, numberOfLines: 1, children: mergeRequest.title ?? "Untitled merge request" })
|
|
4656
4792
|
] }),
|
|
4657
|
-
headerRight ? /* @__PURE__ */
|
|
4793
|
+
headerRight ? /* @__PURE__ */ jsx40(View28, { children: headerRight }) : /* @__PURE__ */ jsx40(
|
|
4658
4794
|
Animated7.View,
|
|
4659
4795
|
{
|
|
4660
4796
|
style: {
|
|
@@ -4664,12 +4800,12 @@ function MergeRequestStatusCard({
|
|
|
4664
4800
|
}
|
|
4665
4801
|
]
|
|
4666
4802
|
},
|
|
4667
|
-
children: /* @__PURE__ */
|
|
4803
|
+
children: /* @__PURE__ */ jsx40(ChevronDown2, { size: 20, color: withAlpha(theme.colors.textMuted, 0.4) })
|
|
4668
4804
|
}
|
|
4669
4805
|
)
|
|
4670
4806
|
] }),
|
|
4671
4807
|
expanded ? /* @__PURE__ */ jsxs22(View28, { style: { marginTop: 16, marginLeft: 56 }, children: [
|
|
4672
|
-
/* @__PURE__ */
|
|
4808
|
+
/* @__PURE__ */ jsx40(
|
|
4673
4809
|
Text,
|
|
4674
4810
|
{
|
|
4675
4811
|
style: {
|
|
@@ -4683,7 +4819,7 @@ function MergeRequestStatusCard({
|
|
|
4683
4819
|
children: status.text
|
|
4684
4820
|
}
|
|
4685
4821
|
),
|
|
4686
|
-
createdTimeAgo ? /* @__PURE__ */
|
|
4822
|
+
createdTimeAgo ? /* @__PURE__ */ jsx40(
|
|
4687
4823
|
Text,
|
|
4688
4824
|
{
|
|
4689
4825
|
style: {
|
|
@@ -4694,8 +4830,8 @@ function MergeRequestStatusCard({
|
|
|
4694
4830
|
children: createdTimeAgo
|
|
4695
4831
|
}
|
|
4696
4832
|
) : null,
|
|
4697
|
-
/* @__PURE__ */
|
|
4698
|
-
mergeRequest.description ? /* @__PURE__ */
|
|
4833
|
+
/* @__PURE__ */ jsx40(Text, { style: { fontSize: 16, fontWeight: "600", color: textColor, marginBottom: 8 }, children: mergeRequest.title ?? "Untitled merge request" }),
|
|
4834
|
+
mergeRequest.description ? /* @__PURE__ */ jsx40(MarkdownText, { markdown: mergeRequest.description, variant: "mergeRequest" }) : null
|
|
4699
4835
|
] }) : null
|
|
4700
4836
|
]
|
|
4701
4837
|
}
|
|
@@ -4703,18 +4839,18 @@ function MergeRequestStatusCard({
|
|
|
4703
4839
|
}
|
|
4704
4840
|
|
|
4705
4841
|
// src/components/merge-requests/ReviewMergeRequestCarousel.tsx
|
|
4706
|
-
import * as
|
|
4842
|
+
import * as React30 from "react";
|
|
4707
4843
|
import { Animated as Animated9, FlatList, View as View31, useWindowDimensions as useWindowDimensions3 } from "react-native";
|
|
4708
4844
|
|
|
4709
4845
|
// src/components/merge-requests/ReviewMergeRequestCard.tsx
|
|
4710
|
-
import * as
|
|
4846
|
+
import * as React29 from "react";
|
|
4711
4847
|
import { ActivityIndicator as ActivityIndicator5, Animated as Animated8, Pressable as Pressable11, View as View30 } from "react-native";
|
|
4712
4848
|
import { Check as Check4, ChevronDown as ChevronDown3, Play as Play3, X as X3 } from "lucide-react-native";
|
|
4713
4849
|
|
|
4714
4850
|
// src/components/merge-requests/ReviewMergeRequestActionButton.tsx
|
|
4715
|
-
import * as
|
|
4851
|
+
import * as React28 from "react";
|
|
4716
4852
|
import { Pressable as Pressable10, View as View29 } from "react-native";
|
|
4717
|
-
import { jsx as
|
|
4853
|
+
import { jsx as jsx41 } from "react/jsx-runtime";
|
|
4718
4854
|
function ReviewMergeRequestActionButton({
|
|
4719
4855
|
accessibilityLabel,
|
|
4720
4856
|
backgroundColor,
|
|
@@ -4723,13 +4859,13 @@ function ReviewMergeRequestActionButton({
|
|
|
4723
4859
|
children,
|
|
4724
4860
|
iconOnly
|
|
4725
4861
|
}) {
|
|
4726
|
-
const [pressed, setPressed] =
|
|
4862
|
+
const [pressed, setPressed] = React28.useState(false);
|
|
4727
4863
|
const height = iconOnly ? 36 : 40;
|
|
4728
4864
|
const width = iconOnly ? 36 : void 0;
|
|
4729
4865
|
const paddingHorizontal = iconOnly ? 0 : 16;
|
|
4730
4866
|
const paddingVertical = iconOnly ? 0 : 8;
|
|
4731
4867
|
const opacity = disabled ? 0.5 : pressed ? 0.9 : 1;
|
|
4732
|
-
return /* @__PURE__ */
|
|
4868
|
+
return /* @__PURE__ */ jsx41(
|
|
4733
4869
|
View29,
|
|
4734
4870
|
{
|
|
4735
4871
|
style: {
|
|
@@ -4744,7 +4880,7 @@ function ReviewMergeRequestActionButton({
|
|
|
4744
4880
|
paddingVertical,
|
|
4745
4881
|
justifyContent: "center"
|
|
4746
4882
|
},
|
|
4747
|
-
children: /* @__PURE__ */
|
|
4883
|
+
children: /* @__PURE__ */ jsx41(
|
|
4748
4884
|
Pressable10,
|
|
4749
4885
|
{
|
|
4750
4886
|
accessibilityRole: "button",
|
|
@@ -4768,7 +4904,7 @@ function ReviewMergeRequestActionButton({
|
|
|
4768
4904
|
}
|
|
4769
4905
|
|
|
4770
4906
|
// src/components/merge-requests/ReviewMergeRequestCard.tsx
|
|
4771
|
-
import { jsx as
|
|
4907
|
+
import { jsx as jsx42, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
4772
4908
|
function ReviewMergeRequestCard({
|
|
4773
4909
|
mr,
|
|
4774
4910
|
index,
|
|
@@ -4785,14 +4921,14 @@ function ReviewMergeRequestCard({
|
|
|
4785
4921
|
onTest
|
|
4786
4922
|
}) {
|
|
4787
4923
|
const theme = useTheme();
|
|
4788
|
-
const status =
|
|
4924
|
+
const status = React29.useMemo(() => getMergeRequestStatusDisplay(mr.status), [mr.status]);
|
|
4789
4925
|
const canAct = mr.status === "open";
|
|
4790
|
-
const rotate =
|
|
4791
|
-
|
|
4926
|
+
const rotate = React29.useRef(new Animated8.Value(isExpanded ? 1 : 0)).current;
|
|
4927
|
+
React29.useEffect(() => {
|
|
4792
4928
|
Animated8.timing(rotate, { toValue: isExpanded ? 1 : 0, duration: 200, useNativeDriver: true }).start();
|
|
4793
4929
|
}, [isExpanded, rotate]);
|
|
4794
4930
|
const position = total > 1 ? `${index + 1}/${total}` : "Merge request";
|
|
4795
|
-
return /* @__PURE__ */
|
|
4931
|
+
return /* @__PURE__ */ jsx42(Pressable11, { onPress: onToggle, style: ({ pressed }) => ({ opacity: pressed ? 0.95 : 1 }), children: /* @__PURE__ */ jsxs23(
|
|
4796
4932
|
Card,
|
|
4797
4933
|
{
|
|
4798
4934
|
padded: false,
|
|
@@ -4806,9 +4942,9 @@ function ReviewMergeRequestCard({
|
|
|
4806
4942
|
],
|
|
4807
4943
|
children: [
|
|
4808
4944
|
/* @__PURE__ */ jsxs23(View30, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [
|
|
4809
|
-
/* @__PURE__ */
|
|
4945
|
+
/* @__PURE__ */ jsx42(Avatar, { size: 40, uri: (creator == null ? void 0 : creator.avatar) ?? null, name: (creator == null ? void 0 : creator.name) ?? void 0 }),
|
|
4810
4946
|
/* @__PURE__ */ jsxs23(View30, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4811
|
-
/* @__PURE__ */
|
|
4947
|
+
/* @__PURE__ */ jsx42(
|
|
4812
4948
|
Text,
|
|
4813
4949
|
{
|
|
4814
4950
|
style: { fontWeight: theme.typography.fontWeight.semibold, color: theme.colors.text, fontSize: 16, lineHeight: 20 },
|
|
@@ -4822,18 +4958,18 @@ function ReviewMergeRequestCard({
|
|
|
4822
4958
|
position
|
|
4823
4959
|
] })
|
|
4824
4960
|
] }),
|
|
4825
|
-
/* @__PURE__ */
|
|
4961
|
+
/* @__PURE__ */ jsx42(
|
|
4826
4962
|
Animated8.View,
|
|
4827
4963
|
{
|
|
4828
4964
|
style: {
|
|
4829
4965
|
transform: [{ rotate: rotate.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "180deg"] }) }]
|
|
4830
4966
|
},
|
|
4831
|
-
children: /* @__PURE__ */
|
|
4967
|
+
children: /* @__PURE__ */ jsx42(ChevronDown3, { size: 20, color: withAlpha(theme.colors.textMuted, 0.4) })
|
|
4832
4968
|
}
|
|
4833
4969
|
)
|
|
4834
4970
|
] }),
|
|
4835
4971
|
isExpanded ? /* @__PURE__ */ jsxs23(View30, { style: { marginTop: 16 }, children: [
|
|
4836
|
-
/* @__PURE__ */
|
|
4972
|
+
/* @__PURE__ */ jsx42(
|
|
4837
4973
|
Text,
|
|
4838
4974
|
{
|
|
4839
4975
|
style: {
|
|
@@ -4847,13 +4983,13 @@ function ReviewMergeRequestCard({
|
|
|
4847
4983
|
children: status.text
|
|
4848
4984
|
}
|
|
4849
4985
|
),
|
|
4850
|
-
/* @__PURE__ */
|
|
4851
|
-
mr.description ? /* @__PURE__ */
|
|
4986
|
+
/* @__PURE__ */ jsx42(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginBottom: 12 }, children: creator ? `${creator.approvedOpenedMergeRequests} approved merge${creator.approvedOpenedMergeRequests !== 1 ? "s" : ""}` : "Loading stats..." }),
|
|
4987
|
+
mr.description ? /* @__PURE__ */ jsx42(MarkdownText, { markdown: mr.description, variant: "mergeRequest" }) : null
|
|
4852
4988
|
] }) : null,
|
|
4853
|
-
/* @__PURE__ */
|
|
4989
|
+
/* @__PURE__ */ jsx42(View30, { style: { height: 1, backgroundColor: withAlpha(theme.colors.borderStrong, 0.5), marginTop: 12, marginBottom: 12 } }),
|
|
4854
4990
|
/* @__PURE__ */ jsxs23(View30, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
4855
4991
|
/* @__PURE__ */ jsxs23(View30, { style: { flexDirection: "row", gap: 8 }, children: [
|
|
4856
|
-
/* @__PURE__ */
|
|
4992
|
+
/* @__PURE__ */ jsx42(
|
|
4857
4993
|
ReviewMergeRequestActionButton,
|
|
4858
4994
|
{
|
|
4859
4995
|
accessibilityLabel: "Reject",
|
|
@@ -4862,12 +4998,12 @@ function ReviewMergeRequestCard({
|
|
|
4862
4998
|
onPress: onReject,
|
|
4863
4999
|
iconOnly: !isExpanded,
|
|
4864
5000
|
children: /* @__PURE__ */ jsxs23(View30, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4865
|
-
/* @__PURE__ */
|
|
4866
|
-
isExpanded ? /* @__PURE__ */
|
|
5001
|
+
/* @__PURE__ */ jsx42(X3, { size: 18, color: "#FFFFFF" }),
|
|
5002
|
+
isExpanded ? /* @__PURE__ */ jsx42(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Reject" }) : null
|
|
4867
5003
|
] })
|
|
4868
5004
|
}
|
|
4869
5005
|
),
|
|
4870
|
-
/* @__PURE__ */
|
|
5006
|
+
/* @__PURE__ */ jsx42(
|
|
4871
5007
|
ReviewMergeRequestActionButton,
|
|
4872
5008
|
{
|
|
4873
5009
|
accessibilityLabel: !canAct ? "Not actionable" : isProcessing ? "Processing" : "Approve",
|
|
@@ -4876,16 +5012,16 @@ function ReviewMergeRequestCard({
|
|
|
4876
5012
|
onPress: onApprove,
|
|
4877
5013
|
iconOnly: !isExpanded,
|
|
4878
5014
|
children: isProcessing ? /* @__PURE__ */ jsxs23(View30, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4879
|
-
/* @__PURE__ */
|
|
4880
|
-
isExpanded ? /* @__PURE__ */
|
|
5015
|
+
/* @__PURE__ */ jsx42(ActivityIndicator5, { size: "small", color: "#FFFFFF" }),
|
|
5016
|
+
isExpanded ? /* @__PURE__ */ jsx42(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Processing" }) : null
|
|
4881
5017
|
] }) : /* @__PURE__ */ jsxs23(View30, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4882
|
-
/* @__PURE__ */
|
|
4883
|
-
isExpanded ? /* @__PURE__ */
|
|
5018
|
+
/* @__PURE__ */ jsx42(Check4, { size: 18, color: "#FFFFFF" }),
|
|
5019
|
+
isExpanded ? /* @__PURE__ */ jsx42(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Approve" }) : null
|
|
4884
5020
|
] })
|
|
4885
5021
|
}
|
|
4886
5022
|
)
|
|
4887
5023
|
] }),
|
|
4888
|
-
/* @__PURE__ */
|
|
5024
|
+
/* @__PURE__ */ jsx42(
|
|
4889
5025
|
ReviewMergeRequestActionButton,
|
|
4890
5026
|
{
|
|
4891
5027
|
accessibilityLabel: "Test",
|
|
@@ -4893,9 +5029,9 @@ function ReviewMergeRequestCard({
|
|
|
4893
5029
|
disabled: isBuilding || isTestingThis,
|
|
4894
5030
|
onPress: onTest,
|
|
4895
5031
|
iconOnly: !isExpanded,
|
|
4896
|
-
children: isTestingThis ? /* @__PURE__ */
|
|
4897
|
-
/* @__PURE__ */
|
|
4898
|
-
isExpanded ? /* @__PURE__ */
|
|
5032
|
+
children: isTestingThis ? /* @__PURE__ */ jsx42(ActivityIndicator5, { size: "small", color: "#888" }) : /* @__PURE__ */ jsxs23(View30, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
5033
|
+
/* @__PURE__ */ jsx42(Play3, { size: 14, color: theme.colors.text }),
|
|
5034
|
+
isExpanded ? /* @__PURE__ */ jsx42(Text, { style: { fontSize: 13, color: theme.colors.text, fontWeight: theme.typography.fontWeight.semibold }, children: "Test" }) : null
|
|
4899
5035
|
] })
|
|
4900
5036
|
}
|
|
4901
5037
|
)
|
|
@@ -4906,7 +5042,7 @@ function ReviewMergeRequestCard({
|
|
|
4906
5042
|
}
|
|
4907
5043
|
|
|
4908
5044
|
// src/components/merge-requests/ReviewMergeRequestCarousel.tsx
|
|
4909
|
-
import { jsx as
|
|
5045
|
+
import { jsx as jsx43, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
4910
5046
|
function ReviewMergeRequestCarousel({
|
|
4911
5047
|
mergeRequests,
|
|
4912
5048
|
creatorStatsById,
|
|
@@ -4920,16 +5056,16 @@ function ReviewMergeRequestCarousel({
|
|
|
4920
5056
|
}) {
|
|
4921
5057
|
const theme = useTheme();
|
|
4922
5058
|
const { width } = useWindowDimensions3();
|
|
4923
|
-
const [expanded, setExpanded] =
|
|
4924
|
-
const carouselScrollX =
|
|
5059
|
+
const [expanded, setExpanded] = React30.useState({});
|
|
5060
|
+
const carouselScrollX = React30.useRef(new Animated9.Value(0)).current;
|
|
4925
5061
|
const peekAmount = 24;
|
|
4926
5062
|
const gap = 16;
|
|
4927
|
-
const cardWidth =
|
|
5063
|
+
const cardWidth = React30.useMemo(() => Math.max(1, width - theme.spacing.lg * 2 - peekAmount), [peekAmount, theme.spacing.lg, width]);
|
|
4928
5064
|
const snapInterval = cardWidth + gap;
|
|
4929
5065
|
const dotColor = theme.scheme === "dark" ? "#FFFFFF" : "#000000";
|
|
4930
5066
|
if (mergeRequests.length === 0) return null;
|
|
4931
5067
|
return /* @__PURE__ */ jsxs24(View31, { style: [{ marginHorizontal: -theme.spacing.lg }, style], children: [
|
|
4932
|
-
/* @__PURE__ */
|
|
5068
|
+
/* @__PURE__ */ jsx43(
|
|
4933
5069
|
FlatList,
|
|
4934
5070
|
{
|
|
4935
5071
|
horizontal: true,
|
|
@@ -4937,13 +5073,13 @@ function ReviewMergeRequestCarousel({
|
|
|
4937
5073
|
keyExtractor: (mr) => mr.id,
|
|
4938
5074
|
showsHorizontalScrollIndicator: false,
|
|
4939
5075
|
contentContainerStyle: { paddingHorizontal: theme.spacing.lg, paddingVertical: theme.spacing.sm },
|
|
4940
|
-
ItemSeparatorComponent: () => /* @__PURE__ */
|
|
5076
|
+
ItemSeparatorComponent: () => /* @__PURE__ */ jsx43(View31, { style: { width: gap } }),
|
|
4941
5077
|
snapToAlignment: "start",
|
|
4942
5078
|
decelerationRate: "fast",
|
|
4943
5079
|
snapToInterval: snapInterval,
|
|
4944
5080
|
disableIntervalMomentum: true,
|
|
4945
5081
|
style: { paddingRight: peekAmount },
|
|
4946
|
-
ListFooterComponent: /* @__PURE__ */
|
|
5082
|
+
ListFooterComponent: /* @__PURE__ */ jsx43(View31, { style: { width: peekAmount } }),
|
|
4947
5083
|
onScroll: Animated9.event([{ nativeEvent: { contentOffset: { x: carouselScrollX } } }], {
|
|
4948
5084
|
useNativeDriver: false
|
|
4949
5085
|
}),
|
|
@@ -4955,7 +5091,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4955
5091
|
const isProcessing = Boolean(processingMrId && processingMrId === item.id);
|
|
4956
5092
|
const isAnyProcessing = Boolean(processingMrId);
|
|
4957
5093
|
const isTestingThis = Boolean(testingMrId && testingMrId === item.id);
|
|
4958
|
-
return /* @__PURE__ */
|
|
5094
|
+
return /* @__PURE__ */ jsx43(View31, { style: { width: cardWidth }, children: /* @__PURE__ */ jsx43(
|
|
4959
5095
|
ReviewMergeRequestCard,
|
|
4960
5096
|
{
|
|
4961
5097
|
mr: item,
|
|
@@ -4976,7 +5112,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4976
5112
|
}
|
|
4977
5113
|
}
|
|
4978
5114
|
),
|
|
4979
|
-
mergeRequests.length >= 1 ? /* @__PURE__ */
|
|
5115
|
+
mergeRequests.length >= 1 ? /* @__PURE__ */ jsx43(View31, { style: { flexDirection: "row", justifyContent: "center", columnGap: 8, marginTop: theme.spacing.md }, children: mergeRequests.map((mr, index) => {
|
|
4980
5116
|
const inputRange = [(index - 1) * snapInterval, index * snapInterval, (index + 1) * snapInterval];
|
|
4981
5117
|
const scale = carouselScrollX.interpolate({
|
|
4982
5118
|
inputRange,
|
|
@@ -4988,7 +5124,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4988
5124
|
outputRange: [0.4, 1, 0.4],
|
|
4989
5125
|
extrapolate: "clamp"
|
|
4990
5126
|
});
|
|
4991
|
-
return /* @__PURE__ */
|
|
5127
|
+
return /* @__PURE__ */ jsx43(
|
|
4992
5128
|
Animated9.View,
|
|
4993
5129
|
{
|
|
4994
5130
|
style: {
|
|
@@ -5007,7 +5143,7 @@ function ReviewMergeRequestCarousel({
|
|
|
5007
5143
|
}
|
|
5008
5144
|
|
|
5009
5145
|
// src/studio/ui/preview-panel/PreviewCollaborateSection.tsx
|
|
5010
|
-
import { Fragment as Fragment5, jsx as
|
|
5146
|
+
import { Fragment as Fragment5, jsx as jsx44, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
5011
5147
|
function PreviewCollaborateSection({
|
|
5012
5148
|
canSubmitMergeRequest,
|
|
5013
5149
|
incomingMergeRequests,
|
|
@@ -5023,13 +5159,13 @@ function PreviewCollaborateSection({
|
|
|
5023
5159
|
onTestMr
|
|
5024
5160
|
}) {
|
|
5025
5161
|
const theme = useTheme();
|
|
5026
|
-
const [submittingMr, setSubmittingMr] =
|
|
5162
|
+
const [submittingMr, setSubmittingMr] = React31.useState(false);
|
|
5027
5163
|
const hasSection = canSubmitMergeRequest || incomingMergeRequests.length > 0 || outgoingMergeRequests.length > 0;
|
|
5028
5164
|
if (!hasSection) return null;
|
|
5029
5165
|
const showActionsSubtitle = canSubmitMergeRequest && onSubmitMergeRequest || onTestMr && incomingMergeRequests.length > 0;
|
|
5030
5166
|
return /* @__PURE__ */ jsxs25(Fragment5, { children: [
|
|
5031
|
-
/* @__PURE__ */
|
|
5032
|
-
showActionsSubtitle ? /* @__PURE__ */
|
|
5167
|
+
/* @__PURE__ */ jsx44(SectionTitle, { marginTop: theme.spacing.xl, children: "Collaborate" }),
|
|
5168
|
+
showActionsSubtitle ? /* @__PURE__ */ jsx44(
|
|
5033
5169
|
Text,
|
|
5034
5170
|
{
|
|
5035
5171
|
style: {
|
|
@@ -5044,7 +5180,7 @@ function PreviewCollaborateSection({
|
|
|
5044
5180
|
children: "Actions"
|
|
5045
5181
|
}
|
|
5046
5182
|
) : null,
|
|
5047
|
-
canSubmitMergeRequest && onSubmitMergeRequest ? /* @__PURE__ */
|
|
5183
|
+
canSubmitMergeRequest && onSubmitMergeRequest ? /* @__PURE__ */ jsx44(
|
|
5048
5184
|
PressableCardRow,
|
|
5049
5185
|
{
|
|
5050
5186
|
accessibilityLabel: "Submit merge request",
|
|
@@ -5075,7 +5211,7 @@ function PreviewCollaborateSection({
|
|
|
5075
5211
|
borderColor: withAlpha("#03DAC6", 0.2),
|
|
5076
5212
|
marginBottom: theme.spacing.sm
|
|
5077
5213
|
},
|
|
5078
|
-
left: /* @__PURE__ */
|
|
5214
|
+
left: /* @__PURE__ */ jsx44(
|
|
5079
5215
|
View32,
|
|
5080
5216
|
{
|
|
5081
5217
|
style: {
|
|
@@ -5087,15 +5223,15 @@ function PreviewCollaborateSection({
|
|
|
5087
5223
|
backgroundColor: withAlpha("#03DAC6", 0.1),
|
|
5088
5224
|
marginRight: theme.spacing.lg
|
|
5089
5225
|
},
|
|
5090
|
-
children: submittingMr ? /* @__PURE__ */
|
|
5226
|
+
children: submittingMr ? /* @__PURE__ */ jsx44(ActivityIndicator6, { color: "#03DAC6", size: "small" }) : /* @__PURE__ */ jsx44(MergeIcon, { width: 20, height: 20, color: "#03DAC6" })
|
|
5091
5227
|
}
|
|
5092
5228
|
),
|
|
5093
|
-
title: /* @__PURE__ */
|
|
5094
|
-
subtitle: /* @__PURE__ */
|
|
5095
|
-
right: /* @__PURE__ */
|
|
5229
|
+
title: /* @__PURE__ */ jsx44(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Submit your new changes" }),
|
|
5230
|
+
subtitle: /* @__PURE__ */ jsx44(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: "Ask to merge this remix to the original app" }),
|
|
5231
|
+
right: /* @__PURE__ */ jsx44(Send2, { size: 16, color: "#03DAC6" })
|
|
5096
5232
|
}
|
|
5097
5233
|
) : null,
|
|
5098
|
-
onTestMr && incomingMergeRequests.length > 0 ? /* @__PURE__ */
|
|
5234
|
+
onTestMr && incomingMergeRequests.length > 0 ? /* @__PURE__ */ jsx44(
|
|
5099
5235
|
ReviewMergeRequestCarousel,
|
|
5100
5236
|
{
|
|
5101
5237
|
mergeRequests: incomingMergeRequests,
|
|
@@ -5109,7 +5245,7 @@ function PreviewCollaborateSection({
|
|
|
5109
5245
|
}
|
|
5110
5246
|
) : null,
|
|
5111
5247
|
outgoingMergeRequests.length > 0 ? /* @__PURE__ */ jsxs25(Fragment5, { children: [
|
|
5112
|
-
/* @__PURE__ */
|
|
5248
|
+
/* @__PURE__ */ jsx44(
|
|
5113
5249
|
Text,
|
|
5114
5250
|
{
|
|
5115
5251
|
style: {
|
|
@@ -5125,13 +5261,13 @@ function PreviewCollaborateSection({
|
|
|
5125
5261
|
children: "History"
|
|
5126
5262
|
}
|
|
5127
5263
|
),
|
|
5128
|
-
outgoingMergeRequests.map((mr) => /* @__PURE__ */
|
|
5264
|
+
outgoingMergeRequests.map((mr) => /* @__PURE__ */ jsx44(View32, { style: { marginBottom: theme.spacing.sm }, children: /* @__PURE__ */ jsx44(MergeRequestStatusCard, { mergeRequest: toMergeRequestSummary(mr) }) }, mr.id))
|
|
5129
5265
|
] }) : null
|
|
5130
5266
|
] });
|
|
5131
5267
|
}
|
|
5132
5268
|
|
|
5133
5269
|
// src/studio/ui/preview-panel/usePreviewPanelData.ts
|
|
5134
|
-
import * as
|
|
5270
|
+
import * as React33 from "react";
|
|
5135
5271
|
|
|
5136
5272
|
// src/data/apps/images/remote.ts
|
|
5137
5273
|
var AppImagesRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -5182,7 +5318,7 @@ var AppImagesRepositoryImpl = class extends BaseRepository {
|
|
|
5182
5318
|
var appImagesRepository = new AppImagesRepositoryImpl(appImagesRemoteDataSource);
|
|
5183
5319
|
|
|
5184
5320
|
// src/studio/hooks/useAppStats.ts
|
|
5185
|
-
import * as
|
|
5321
|
+
import * as React32 from "react";
|
|
5186
5322
|
import * as Haptics2 from "expo-haptics";
|
|
5187
5323
|
|
|
5188
5324
|
// src/data/likes/remote.ts
|
|
@@ -5251,34 +5387,34 @@ function useAppStats({
|
|
|
5251
5387
|
initialIsLiked = false,
|
|
5252
5388
|
onOpenComments
|
|
5253
5389
|
}) {
|
|
5254
|
-
const [likeCount, setLikeCount] =
|
|
5255
|
-
const [commentCount, setCommentCount] =
|
|
5256
|
-
const [forkCount, setForkCount] =
|
|
5257
|
-
const [isLiked, setIsLiked] =
|
|
5258
|
-
const didMutateRef =
|
|
5259
|
-
const lastAppIdRef =
|
|
5260
|
-
|
|
5390
|
+
const [likeCount, setLikeCount] = React32.useState(initialLikes);
|
|
5391
|
+
const [commentCount, setCommentCount] = React32.useState(initialComments);
|
|
5392
|
+
const [forkCount, setForkCount] = React32.useState(initialForks);
|
|
5393
|
+
const [isLiked, setIsLiked] = React32.useState(initialIsLiked);
|
|
5394
|
+
const didMutateRef = React32.useRef(false);
|
|
5395
|
+
const lastAppIdRef = React32.useRef("");
|
|
5396
|
+
React32.useEffect(() => {
|
|
5261
5397
|
if (lastAppIdRef.current === appId) return;
|
|
5262
5398
|
lastAppIdRef.current = appId;
|
|
5263
5399
|
didMutateRef.current = false;
|
|
5264
5400
|
}, [appId]);
|
|
5265
|
-
|
|
5401
|
+
React32.useEffect(() => {
|
|
5266
5402
|
if (didMutateRef.current) return;
|
|
5267
5403
|
setLikeCount(initialLikes);
|
|
5268
5404
|
}, [appId, initialLikes]);
|
|
5269
|
-
|
|
5405
|
+
React32.useEffect(() => {
|
|
5270
5406
|
if (didMutateRef.current) return;
|
|
5271
5407
|
setCommentCount(initialComments);
|
|
5272
5408
|
}, [appId, initialComments]);
|
|
5273
|
-
|
|
5409
|
+
React32.useEffect(() => {
|
|
5274
5410
|
if (didMutateRef.current) return;
|
|
5275
5411
|
setForkCount(initialForks);
|
|
5276
5412
|
}, [appId, initialForks]);
|
|
5277
|
-
|
|
5413
|
+
React32.useEffect(() => {
|
|
5278
5414
|
if (didMutateRef.current) return;
|
|
5279
5415
|
setIsLiked(initialIsLiked);
|
|
5280
5416
|
}, [appId, initialIsLiked]);
|
|
5281
|
-
const handleLike =
|
|
5417
|
+
const handleLike = React32.useCallback(async () => {
|
|
5282
5418
|
var _a, _b;
|
|
5283
5419
|
if (!appId) return;
|
|
5284
5420
|
didMutateRef.current = true;
|
|
@@ -5302,7 +5438,7 @@ function useAppStats({
|
|
|
5302
5438
|
setLikeCount((prev) => Math.max(0, prev + (newIsLiked ? -1 : 1)));
|
|
5303
5439
|
}
|
|
5304
5440
|
}, [appId, isLiked, likeCount]);
|
|
5305
|
-
const handleOpenComments =
|
|
5441
|
+
const handleOpenComments = React32.useCallback(() => {
|
|
5306
5442
|
if (!appId) return;
|
|
5307
5443
|
try {
|
|
5308
5444
|
void Haptics2.impactAsync(Haptics2.ImpactFeedbackStyle.Light);
|
|
@@ -5317,11 +5453,11 @@ function useAppStats({
|
|
|
5317
5453
|
var LIKE_DEBUG_PREFIX = "[COMERGE_LIKE_DEBUG]";
|
|
5318
5454
|
function usePreviewPanelData(params) {
|
|
5319
5455
|
const { app, isOwner, outgoingMergeRequests, onOpenComments, commentCountOverride } = params;
|
|
5320
|
-
const [imageUrl, setImageUrl] =
|
|
5321
|
-
const [imageLoaded, setImageLoaded] =
|
|
5322
|
-
const [insights, setInsights] =
|
|
5323
|
-
const [creator, setCreator] =
|
|
5324
|
-
|
|
5456
|
+
const [imageUrl, setImageUrl] = React33.useState(null);
|
|
5457
|
+
const [imageLoaded, setImageLoaded] = React33.useState(false);
|
|
5458
|
+
const [insights, setInsights] = React33.useState({ likes: 0, comments: 0, forks: 0, downloads: 0 });
|
|
5459
|
+
const [creator, setCreator] = React33.useState(null);
|
|
5460
|
+
React33.useEffect(() => {
|
|
5325
5461
|
if (!(app == null ? void 0 : app.id)) return;
|
|
5326
5462
|
let cancelled = false;
|
|
5327
5463
|
(async () => {
|
|
@@ -5336,7 +5472,7 @@ function usePreviewPanelData(params) {
|
|
|
5336
5472
|
cancelled = true;
|
|
5337
5473
|
};
|
|
5338
5474
|
}, [app == null ? void 0 : app.id]);
|
|
5339
|
-
|
|
5475
|
+
React33.useEffect(() => {
|
|
5340
5476
|
if (!(app == null ? void 0 : app.createdBy)) return;
|
|
5341
5477
|
let cancelled = false;
|
|
5342
5478
|
(async () => {
|
|
@@ -5352,10 +5488,10 @@ function usePreviewPanelData(params) {
|
|
|
5352
5488
|
cancelled = true;
|
|
5353
5489
|
};
|
|
5354
5490
|
}, [app == null ? void 0 : app.createdBy]);
|
|
5355
|
-
|
|
5491
|
+
React33.useEffect(() => {
|
|
5356
5492
|
setImageLoaded(false);
|
|
5357
5493
|
}, [app == null ? void 0 : app.id]);
|
|
5358
|
-
|
|
5494
|
+
React33.useEffect(() => {
|
|
5359
5495
|
if (!(app == null ? void 0 : app.id)) return;
|
|
5360
5496
|
let cancelled = false;
|
|
5361
5497
|
(async () => {
|
|
@@ -5380,7 +5516,7 @@ function usePreviewPanelData(params) {
|
|
|
5380
5516
|
cancelled = true;
|
|
5381
5517
|
};
|
|
5382
5518
|
}, [app == null ? void 0 : app.id]);
|
|
5383
|
-
|
|
5519
|
+
React33.useEffect(() => {
|
|
5384
5520
|
if (!(app == null ? void 0 : app.id)) return;
|
|
5385
5521
|
log.debug(
|
|
5386
5522
|
`${LIKE_DEBUG_PREFIX} usePreviewPanelData.appChanged appId=${app.id} app.isLiked=${String(app.isLiked)}`
|
|
@@ -5394,7 +5530,7 @@ function usePreviewPanelData(params) {
|
|
|
5394
5530
|
initialIsLiked: Boolean(app == null ? void 0 : app.isLiked),
|
|
5395
5531
|
onOpenComments
|
|
5396
5532
|
});
|
|
5397
|
-
const canSubmitMergeRequest =
|
|
5533
|
+
const canSubmitMergeRequest = React33.useMemo(() => {
|
|
5398
5534
|
if (!isOwner) return false;
|
|
5399
5535
|
if (!app) return false;
|
|
5400
5536
|
if (!app.forkedFromAppId) return false;
|
|
@@ -5416,7 +5552,7 @@ function usePreviewPanelData(params) {
|
|
|
5416
5552
|
}
|
|
5417
5553
|
|
|
5418
5554
|
// src/studio/ui/PreviewPanel.tsx
|
|
5419
|
-
import { jsx as
|
|
5555
|
+
import { jsx as jsx45, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
5420
5556
|
function PreviewPanel({
|
|
5421
5557
|
app,
|
|
5422
5558
|
loading,
|
|
@@ -5447,16 +5583,16 @@ function PreviewPanel({
|
|
|
5447
5583
|
onOpenComments,
|
|
5448
5584
|
commentCountOverride
|
|
5449
5585
|
});
|
|
5450
|
-
const header = /* @__PURE__ */
|
|
5586
|
+
const header = /* @__PURE__ */ jsx45(PreviewPanelHeader, { isOwner, onClose, onNavigateHome, onGoToChat });
|
|
5451
5587
|
if (loading || !app) {
|
|
5452
|
-
return /* @__PURE__ */
|
|
5453
|
-
/* @__PURE__ */
|
|
5454
|
-
/* @__PURE__ */
|
|
5455
|
-
/* @__PURE__ */
|
|
5588
|
+
return /* @__PURE__ */ jsx45(PreviewPage, { header, children: /* @__PURE__ */ jsxs26(View33, { style: { flex: 1, justifyContent: "center", alignItems: "center", padding: 24 }, children: [
|
|
5589
|
+
/* @__PURE__ */ jsx45(ActivityIndicator7, {}),
|
|
5590
|
+
/* @__PURE__ */ jsx45(View33, { style: { height: 12 } }),
|
|
5591
|
+
/* @__PURE__ */ jsx45(Text, { variant: "bodyMuted", children: "Loading app\u2026" })
|
|
5456
5592
|
] }) });
|
|
5457
5593
|
}
|
|
5458
5594
|
return /* @__PURE__ */ jsxs26(PreviewPage, { header, children: [
|
|
5459
|
-
/* @__PURE__ */
|
|
5595
|
+
/* @__PURE__ */ jsx45(
|
|
5460
5596
|
PreviewHeroSection,
|
|
5461
5597
|
{
|
|
5462
5598
|
appStatus: app.status,
|
|
@@ -5474,8 +5610,8 @@ function PreviewPanel({
|
|
|
5474
5610
|
}
|
|
5475
5611
|
}
|
|
5476
5612
|
),
|
|
5477
|
-
/* @__PURE__ */
|
|
5478
|
-
/* @__PURE__ */
|
|
5613
|
+
/* @__PURE__ */ jsx45(PreviewMetaSection, { app, isOwner, creator, downloadsCount: insights.downloads }),
|
|
5614
|
+
/* @__PURE__ */ jsx45(
|
|
5479
5615
|
PreviewCustomizeSection,
|
|
5480
5616
|
{
|
|
5481
5617
|
app,
|
|
@@ -5486,7 +5622,7 @@ function PreviewPanel({
|
|
|
5486
5622
|
onStartDraw
|
|
5487
5623
|
}
|
|
5488
5624
|
),
|
|
5489
|
-
/* @__PURE__ */
|
|
5625
|
+
/* @__PURE__ */ jsx45(
|
|
5490
5626
|
PreviewCollaborateSection,
|
|
5491
5627
|
{
|
|
5492
5628
|
canSubmitMergeRequest,
|
|
@@ -5507,23 +5643,23 @@ function PreviewPanel({
|
|
|
5507
5643
|
}
|
|
5508
5644
|
|
|
5509
5645
|
// src/studio/ui/ChatPanel.tsx
|
|
5510
|
-
import * as
|
|
5646
|
+
import * as React38 from "react";
|
|
5511
5647
|
import { ActivityIndicator as ActivityIndicator8, View as View41 } from "react-native";
|
|
5512
5648
|
|
|
5513
5649
|
// src/components/chat/ChatPage.tsx
|
|
5514
|
-
import * as
|
|
5515
|
-
import { Keyboard as Keyboard4, Platform as
|
|
5650
|
+
import * as React36 from "react";
|
|
5651
|
+
import { Keyboard as Keyboard4, Platform as Platform9, View as View37 } from "react-native";
|
|
5516
5652
|
import { useSafeAreaInsets as useSafeAreaInsets4 } from "react-native-safe-area-context";
|
|
5517
5653
|
|
|
5518
5654
|
// src/components/chat/ChatMessageList.tsx
|
|
5519
|
-
import * as
|
|
5520
|
-
import {
|
|
5655
|
+
import * as React35 from "react";
|
|
5656
|
+
import { View as View36 } from "react-native";
|
|
5521
5657
|
import { BottomSheetFlatList } from "@gorhom/bottom-sheet";
|
|
5522
5658
|
|
|
5523
5659
|
// src/components/chat/ChatMessageBubble.tsx
|
|
5524
5660
|
import { View as View34 } from "react-native";
|
|
5525
5661
|
import { CheckCheck as CheckCheck2, GitMerge as GitMerge2 } from "lucide-react-native";
|
|
5526
|
-
import { jsx as
|
|
5662
|
+
import { jsx as jsx46, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
5527
5663
|
function ChatMessageBubble({ message, renderContent, style }) {
|
|
5528
5664
|
var _a, _b;
|
|
5529
5665
|
const theme = useTheme();
|
|
@@ -5537,7 +5673,7 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5537
5673
|
const bubbleVariant = isHuman ? "surface" : "surfaceRaised";
|
|
5538
5674
|
const cornerStyle = isHuman ? { borderTopRightRadius: 0 } : { borderTopLeftRadius: 0 };
|
|
5539
5675
|
const bodyColor = metaStatus === "success" ? theme.colors.success : metaStatus === "error" ? theme.colors.danger : void 0;
|
|
5540
|
-
return /* @__PURE__ */
|
|
5676
|
+
return /* @__PURE__ */ jsx46(View34, { style: [align, style], children: /* @__PURE__ */ jsx46(
|
|
5541
5677
|
Surface,
|
|
5542
5678
|
{
|
|
5543
5679
|
variant: bubbleVariant,
|
|
@@ -5553,26 +5689,26 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5553
5689
|
cornerStyle
|
|
5554
5690
|
],
|
|
5555
5691
|
children: /* @__PURE__ */ jsxs27(View34, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5556
|
-
isMergeCompleted ? /* @__PURE__ */
|
|
5557
|
-
isMergeApproved ? /* @__PURE__ */
|
|
5558
|
-
/* @__PURE__ */
|
|
5692
|
+
isMergeCompleted ? /* @__PURE__ */ jsx46(CheckCheck2, { size: 16, color: theme.colors.success, style: { marginRight: theme.spacing.sm } }) : null,
|
|
5693
|
+
isMergeApproved ? /* @__PURE__ */ jsx46(GitMerge2, { size: 16, color: theme.colors.text, style: { marginRight: theme.spacing.sm } }) : null,
|
|
5694
|
+
/* @__PURE__ */ jsx46(View34, { style: { flexShrink: 1, minWidth: 0 }, children: renderContent ? renderContent(message) : /* @__PURE__ */ jsx46(MarkdownText, { markdown: message.content, variant: "chat", bodyColor }) })
|
|
5559
5695
|
] })
|
|
5560
5696
|
}
|
|
5561
5697
|
) });
|
|
5562
5698
|
}
|
|
5563
5699
|
|
|
5564
5700
|
// src/components/chat/TypingIndicator.tsx
|
|
5565
|
-
import * as
|
|
5701
|
+
import * as React34 from "react";
|
|
5566
5702
|
import { Animated as Animated10, View as View35 } from "react-native";
|
|
5567
|
-
import { jsx as
|
|
5703
|
+
import { jsx as jsx47 } from "react/jsx-runtime";
|
|
5568
5704
|
function TypingIndicator({ style }) {
|
|
5569
5705
|
const theme = useTheme();
|
|
5570
5706
|
const dotColor = theme.colors.textSubtle;
|
|
5571
|
-
const anims =
|
|
5707
|
+
const anims = React34.useMemo(
|
|
5572
5708
|
() => [new Animated10.Value(0.3), new Animated10.Value(0.3), new Animated10.Value(0.3)],
|
|
5573
5709
|
[]
|
|
5574
5710
|
);
|
|
5575
|
-
|
|
5711
|
+
React34.useEffect(() => {
|
|
5576
5712
|
const loops = [];
|
|
5577
5713
|
anims.forEach((a, idx) => {
|
|
5578
5714
|
const seq = Animated10.sequence([
|
|
@@ -5587,7 +5723,7 @@ function TypingIndicator({ style }) {
|
|
|
5587
5723
|
loops.forEach((l) => l.stop());
|
|
5588
5724
|
};
|
|
5589
5725
|
}, [anims]);
|
|
5590
|
-
return /* @__PURE__ */
|
|
5726
|
+
return /* @__PURE__ */ jsx47(View35, { style: [{ flexDirection: "row", alignItems: "center" }, style], children: anims.map((a, i) => /* @__PURE__ */ jsx47(
|
|
5591
5727
|
Animated10.View,
|
|
5592
5728
|
{
|
|
5593
5729
|
style: {
|
|
@@ -5605,8 +5741,8 @@ function TypingIndicator({ style }) {
|
|
|
5605
5741
|
}
|
|
5606
5742
|
|
|
5607
5743
|
// src/components/chat/ChatMessageList.tsx
|
|
5608
|
-
import { jsx as
|
|
5609
|
-
var ChatMessageList =
|
|
5744
|
+
import { jsx as jsx48, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
5745
|
+
var ChatMessageList = React35.forwardRef(
|
|
5610
5746
|
({
|
|
5611
5747
|
messages,
|
|
5612
5748
|
showTypingIndicator = false,
|
|
@@ -5617,23 +5753,23 @@ var ChatMessageList = React33.forwardRef(
|
|
|
5617
5753
|
nearBottomThreshold = 200
|
|
5618
5754
|
}, ref) => {
|
|
5619
5755
|
const theme = useTheme();
|
|
5620
|
-
const listRef =
|
|
5621
|
-
const nearBottomRef =
|
|
5622
|
-
const initialScrollDoneRef =
|
|
5623
|
-
const lastMessageIdRef =
|
|
5624
|
-
const
|
|
5756
|
+
const listRef = React35.useRef(null);
|
|
5757
|
+
const nearBottomRef = React35.useRef(true);
|
|
5758
|
+
const initialScrollDoneRef = React35.useRef(false);
|
|
5759
|
+
const lastMessageIdRef = React35.useRef(null);
|
|
5760
|
+
const data = React35.useMemo(() => {
|
|
5761
|
+
return [...messages].reverse();
|
|
5762
|
+
}, [messages]);
|
|
5763
|
+
const scrollToBottom = React35.useCallback((options) => {
|
|
5625
5764
|
var _a;
|
|
5626
5765
|
const animated = (options == null ? void 0 : options.animated) ?? true;
|
|
5627
|
-
(_a = listRef.current) == null ? void 0 : _a.
|
|
5766
|
+
(_a = listRef.current) == null ? void 0 : _a.scrollToOffset({ offset: 0, animated });
|
|
5628
5767
|
}, []);
|
|
5629
|
-
|
|
5630
|
-
const handleScroll =
|
|
5768
|
+
React35.useImperativeHandle(ref, () => ({ scrollToBottom }), [scrollToBottom]);
|
|
5769
|
+
const handleScroll = React35.useCallback(
|
|
5631
5770
|
(e) => {
|
|
5632
5771
|
const { contentOffset, contentSize, layoutMeasurement } = e.nativeEvent;
|
|
5633
|
-
const distanceFromBottom = Math.max(
|
|
5634
|
-
contentSize.height - Math.max(bottomInset, 0) - (contentOffset.y + layoutMeasurement.height),
|
|
5635
|
-
0
|
|
5636
|
-
);
|
|
5772
|
+
const distanceFromBottom = Math.max(contentOffset.y - Math.max(bottomInset, 0), 0);
|
|
5637
5773
|
const isNear = distanceFromBottom <= nearBottomThreshold;
|
|
5638
5774
|
if (nearBottomRef.current !== isNear) {
|
|
5639
5775
|
nearBottomRef.current = isNear;
|
|
@@ -5642,16 +5778,7 @@ var ChatMessageList = React33.forwardRef(
|
|
|
5642
5778
|
},
|
|
5643
5779
|
[bottomInset, nearBottomThreshold, onNearBottomChange]
|
|
5644
5780
|
);
|
|
5645
|
-
|
|
5646
|
-
var _a;
|
|
5647
|
-
if (initialScrollDoneRef.current) return;
|
|
5648
|
-
if (messages.length === 0) return;
|
|
5649
|
-
initialScrollDoneRef.current = true;
|
|
5650
|
-
lastMessageIdRef.current = ((_a = messages[messages.length - 1]) == null ? void 0 : _a.id) ?? null;
|
|
5651
|
-
const id = requestAnimationFrame(() => scrollToBottom({ animated: false }));
|
|
5652
|
-
return () => cancelAnimationFrame(id);
|
|
5653
|
-
}, [messages, scrollToBottom]);
|
|
5654
|
-
React33.useEffect(() => {
|
|
5781
|
+
React35.useEffect(() => {
|
|
5655
5782
|
if (!initialScrollDoneRef.current) return;
|
|
5656
5783
|
const lastId = messages.length > 0 ? messages[messages.length - 1].id : null;
|
|
5657
5784
|
const prevLastId = lastMessageIdRef.current;
|
|
@@ -5661,42 +5788,44 @@ var ChatMessageList = React33.forwardRef(
|
|
|
5661
5788
|
const id = requestAnimationFrame(() => scrollToBottom({ animated: true }));
|
|
5662
5789
|
return () => cancelAnimationFrame(id);
|
|
5663
5790
|
}, [messages, scrollToBottom]);
|
|
5664
|
-
|
|
5791
|
+
React35.useEffect(() => {
|
|
5665
5792
|
if (showTypingIndicator && nearBottomRef.current) {
|
|
5666
5793
|
const id = requestAnimationFrame(() => scrollToBottom({ animated: true }));
|
|
5667
5794
|
return () => cancelAnimationFrame(id);
|
|
5668
5795
|
}
|
|
5669
5796
|
return void 0;
|
|
5670
5797
|
}, [showTypingIndicator, scrollToBottom]);
|
|
5671
|
-
|
|
5672
|
-
if (!initialScrollDoneRef.current) return;
|
|
5673
|
-
if (!nearBottomRef.current) return;
|
|
5674
|
-
const id = requestAnimationFrame(() => scrollToBottom({ animated: false }));
|
|
5675
|
-
return () => cancelAnimationFrame(id);
|
|
5676
|
-
}, [bottomInset, scrollToBottom]);
|
|
5677
|
-
return /* @__PURE__ */ jsx46(
|
|
5798
|
+
return /* @__PURE__ */ jsx48(
|
|
5678
5799
|
BottomSheetFlatList,
|
|
5679
5800
|
{
|
|
5680
5801
|
ref: listRef,
|
|
5681
|
-
|
|
5802
|
+
inverted: true,
|
|
5803
|
+
data,
|
|
5682
5804
|
keyExtractor: (m) => m.id,
|
|
5683
|
-
keyboardDismissMode: Platform6.OS === "ios" ? "interactive" : "on-drag",
|
|
5684
5805
|
keyboardShouldPersistTaps: "handled",
|
|
5685
5806
|
onScroll: handleScroll,
|
|
5686
5807
|
scrollEventThrottle: 16,
|
|
5687
5808
|
showsVerticalScrollIndicator: false,
|
|
5809
|
+
onContentSizeChange: () => {
|
|
5810
|
+
if (initialScrollDoneRef.current) return;
|
|
5811
|
+
initialScrollDoneRef.current = true;
|
|
5812
|
+
lastMessageIdRef.current = messages.length > 0 ? messages[messages.length - 1].id : null;
|
|
5813
|
+
nearBottomRef.current = true;
|
|
5814
|
+
onNearBottomChange == null ? void 0 : onNearBottomChange(true);
|
|
5815
|
+
requestAnimationFrame(() => scrollToBottom({ animated: false }));
|
|
5816
|
+
},
|
|
5688
5817
|
contentContainerStyle: [
|
|
5689
5818
|
{
|
|
5690
5819
|
paddingHorizontal: theme.spacing.lg,
|
|
5691
|
-
|
|
5692
|
-
paddingBottom: theme.spacing.sm
|
|
5820
|
+
paddingVertical: theme.spacing.sm
|
|
5693
5821
|
},
|
|
5694
5822
|
contentStyle
|
|
5695
5823
|
],
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5824
|
+
ItemSeparatorComponent: () => /* @__PURE__ */ jsx48(View36, { style: { height: theme.spacing.sm } }),
|
|
5825
|
+
renderItem: ({ item }) => /* @__PURE__ */ jsx48(ChatMessageBubble, { message: item, renderContent: renderMessageContent }),
|
|
5826
|
+
ListHeaderComponent: /* @__PURE__ */ jsxs28(View36, { children: [
|
|
5827
|
+
showTypingIndicator ? /* @__PURE__ */ jsx48(View36, { style: { marginTop: theme.spacing.sm, alignSelf: "flex-start", paddingHorizontal: theme.spacing.lg }, children: /* @__PURE__ */ jsx48(TypingIndicator, {}) }) : null,
|
|
5828
|
+
bottomInset > 0 ? /* @__PURE__ */ jsx48(View36, { style: { height: bottomInset } }) : null
|
|
5700
5829
|
] })
|
|
5701
5830
|
}
|
|
5702
5831
|
);
|
|
@@ -5705,7 +5834,7 @@ var ChatMessageList = React33.forwardRef(
|
|
|
5705
5834
|
ChatMessageList.displayName = "ChatMessageList";
|
|
5706
5835
|
|
|
5707
5836
|
// src/components/chat/ChatPage.tsx
|
|
5708
|
-
import { jsx as
|
|
5837
|
+
import { jsx as jsx49, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
5709
5838
|
function ChatPage({
|
|
5710
5839
|
header,
|
|
5711
5840
|
messages,
|
|
@@ -5715,15 +5844,16 @@ function ChatPage({
|
|
|
5715
5844
|
composer,
|
|
5716
5845
|
overlay,
|
|
5717
5846
|
style,
|
|
5847
|
+
composerHorizontalPadding,
|
|
5718
5848
|
onNearBottomChange,
|
|
5719
5849
|
listRef
|
|
5720
5850
|
}) {
|
|
5721
5851
|
const theme = useTheme();
|
|
5722
5852
|
const insets = useSafeAreaInsets4();
|
|
5723
|
-
const [composerHeight, setComposerHeight] =
|
|
5724
|
-
const [keyboardVisible, setKeyboardVisible] =
|
|
5725
|
-
|
|
5726
|
-
if (
|
|
5853
|
+
const [composerHeight, setComposerHeight] = React36.useState(0);
|
|
5854
|
+
const [keyboardVisible, setKeyboardVisible] = React36.useState(false);
|
|
5855
|
+
React36.useEffect(() => {
|
|
5856
|
+
if (Platform9.OS !== "ios") return;
|
|
5727
5857
|
const show = Keyboard4.addListener("keyboardWillShow", () => setKeyboardVisible(true));
|
|
5728
5858
|
const hide = Keyboard4.addListener("keyboardWillHide", () => setKeyboardVisible(false));
|
|
5729
5859
|
return () => {
|
|
@@ -5731,28 +5861,28 @@ function ChatPage({
|
|
|
5731
5861
|
hide.remove();
|
|
5732
5862
|
};
|
|
5733
5863
|
}, []);
|
|
5734
|
-
const footerBottomPadding =
|
|
5864
|
+
const footerBottomPadding = Platform9.OS === "ios" ? keyboardVisible ? 0 : insets.bottom : insets.bottom + 10;
|
|
5735
5865
|
const overlayBottom = composerHeight + footerBottomPadding + theme.spacing.lg;
|
|
5736
5866
|
const bottomInset = composerHeight + footerBottomPadding + theme.spacing.xl;
|
|
5737
|
-
const resolvedOverlay =
|
|
5867
|
+
const resolvedOverlay = React36.useMemo(() => {
|
|
5738
5868
|
var _a;
|
|
5739
5869
|
if (!overlay) return null;
|
|
5740
|
-
if (!
|
|
5870
|
+
if (!React36.isValidElement(overlay)) return overlay;
|
|
5741
5871
|
const prevStyle = (_a = overlay.props) == null ? void 0 : _a.style;
|
|
5742
|
-
return
|
|
5872
|
+
return React36.cloneElement(overlay, {
|
|
5743
5873
|
style: [prevStyle, { bottom: overlayBottom }]
|
|
5744
5874
|
});
|
|
5745
5875
|
}, [overlay, overlayBottom]);
|
|
5746
5876
|
return /* @__PURE__ */ jsxs29(View37, { style: [{ flex: 1 }, style], children: [
|
|
5747
|
-
header ? /* @__PURE__ */
|
|
5748
|
-
topBanner ? /* @__PURE__ */
|
|
5877
|
+
header ? /* @__PURE__ */ jsx49(View37, { children: header }) : null,
|
|
5878
|
+
topBanner ? /* @__PURE__ */ jsx49(View37, { style: { paddingHorizontal: theme.spacing.lg, paddingTop: theme.spacing.sm }, children: topBanner }) : null,
|
|
5749
5879
|
/* @__PURE__ */ jsxs29(View37, { style: { flex: 1 }, children: [
|
|
5750
5880
|
/* @__PURE__ */ jsxs29(
|
|
5751
5881
|
View37,
|
|
5752
5882
|
{
|
|
5753
5883
|
style: { flex: 1 },
|
|
5754
5884
|
children: [
|
|
5755
|
-
/* @__PURE__ */
|
|
5885
|
+
/* @__PURE__ */ jsx49(
|
|
5756
5886
|
ChatMessageList,
|
|
5757
5887
|
{
|
|
5758
5888
|
ref: listRef,
|
|
@@ -5767,7 +5897,7 @@ function ChatPage({
|
|
|
5767
5897
|
]
|
|
5768
5898
|
}
|
|
5769
5899
|
),
|
|
5770
|
-
/* @__PURE__ */
|
|
5900
|
+
/* @__PURE__ */ jsx49(
|
|
5771
5901
|
View37,
|
|
5772
5902
|
{
|
|
5773
5903
|
style: {
|
|
@@ -5775,11 +5905,11 @@ function ChatPage({
|
|
|
5775
5905
|
left: 0,
|
|
5776
5906
|
right: 0,
|
|
5777
5907
|
bottom: 0,
|
|
5778
|
-
paddingHorizontal: theme.spacing.
|
|
5908
|
+
paddingHorizontal: composerHorizontalPadding ?? theme.spacing.md,
|
|
5779
5909
|
paddingTop: theme.spacing.sm,
|
|
5780
5910
|
paddingBottom: footerBottomPadding
|
|
5781
5911
|
},
|
|
5782
|
-
children: /* @__PURE__ */
|
|
5912
|
+
children: /* @__PURE__ */ jsx49(
|
|
5783
5913
|
ChatComposer,
|
|
5784
5914
|
{
|
|
5785
5915
|
...composer,
|
|
@@ -5794,15 +5924,15 @@ function ChatPage({
|
|
|
5794
5924
|
}
|
|
5795
5925
|
|
|
5796
5926
|
// src/components/chat/ScrollToBottomButton.tsx
|
|
5797
|
-
import * as
|
|
5927
|
+
import * as React37 from "react";
|
|
5798
5928
|
import { Pressable as Pressable12, View as View38 } from "react-native";
|
|
5799
5929
|
import Animated11, { Easing as Easing2, useAnimatedStyle as useAnimatedStyle2, useSharedValue as useSharedValue2, withTiming as withTiming2 } from "react-native-reanimated";
|
|
5800
|
-
import { jsx as
|
|
5930
|
+
import { jsx as jsx50 } from "react/jsx-runtime";
|
|
5801
5931
|
function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
5802
5932
|
const theme = useTheme();
|
|
5803
5933
|
const progress = useSharedValue2(visible ? 1 : 0);
|
|
5804
|
-
const [pressed, setPressed] =
|
|
5805
|
-
|
|
5934
|
+
const [pressed, setPressed] = React37.useState(false);
|
|
5935
|
+
React37.useEffect(() => {
|
|
5806
5936
|
progress.value = withTiming2(visible ? 1 : 0, { duration: 200, easing: Easing2.out(Easing2.ease) });
|
|
5807
5937
|
}, [progress, visible]);
|
|
5808
5938
|
const animStyle = useAnimatedStyle2(() => ({
|
|
@@ -5811,7 +5941,7 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5811
5941
|
}));
|
|
5812
5942
|
const bg = theme.scheme === "dark" ? "rgba(39,39,42,0.9)" : "rgba(244,244,245,0.95)";
|
|
5813
5943
|
const border = theme.scheme === "dark" ? withAlpha("#FFFFFF", 0.12) : withAlpha("#000000", 0.08);
|
|
5814
|
-
return /* @__PURE__ */
|
|
5944
|
+
return /* @__PURE__ */ jsx50(
|
|
5815
5945
|
Animated11.View,
|
|
5816
5946
|
{
|
|
5817
5947
|
pointerEvents: visible ? "auto" : "none",
|
|
@@ -5825,7 +5955,7 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5825
5955
|
style,
|
|
5826
5956
|
animStyle
|
|
5827
5957
|
],
|
|
5828
|
-
children: /* @__PURE__ */
|
|
5958
|
+
children: /* @__PURE__ */ jsx50(
|
|
5829
5959
|
View38,
|
|
5830
5960
|
{
|
|
5831
5961
|
style: {
|
|
@@ -5844,7 +5974,7 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5844
5974
|
elevation: 5,
|
|
5845
5975
|
opacity: pressed ? 0.85 : 1
|
|
5846
5976
|
},
|
|
5847
|
-
children: /* @__PURE__ */
|
|
5977
|
+
children: /* @__PURE__ */ jsx50(
|
|
5848
5978
|
Pressable12,
|
|
5849
5979
|
{
|
|
5850
5980
|
onPress,
|
|
@@ -5863,7 +5993,7 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5863
5993
|
|
|
5864
5994
|
// src/components/chat/ChatHeader.tsx
|
|
5865
5995
|
import { StyleSheet as StyleSheet4 } from "react-native";
|
|
5866
|
-
import { jsx as
|
|
5996
|
+
import { jsx as jsx51 } from "react/jsx-runtime";
|
|
5867
5997
|
function ChatHeader({ left, right, center, style }) {
|
|
5868
5998
|
const flattenedStyle = StyleSheet4.flatten([
|
|
5869
5999
|
{
|
|
@@ -5871,7 +6001,7 @@ function ChatHeader({ left, right, center, style }) {
|
|
|
5871
6001
|
},
|
|
5872
6002
|
style
|
|
5873
6003
|
]);
|
|
5874
|
-
return /* @__PURE__ */
|
|
6004
|
+
return /* @__PURE__ */ jsx51(
|
|
5875
6005
|
StudioSheetHeader,
|
|
5876
6006
|
{
|
|
5877
6007
|
left,
|
|
@@ -5884,12 +6014,12 @@ function ChatHeader({ left, right, center, style }) {
|
|
|
5884
6014
|
|
|
5885
6015
|
// src/components/chat/ForkNoticeBanner.tsx
|
|
5886
6016
|
import { View as View40 } from "react-native";
|
|
5887
|
-
import { jsx as
|
|
6017
|
+
import { jsx as jsx52, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
5888
6018
|
function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
5889
6019
|
const theme = useTheme();
|
|
5890
6020
|
const resolvedTitle = title ?? (isOwner ? "Remixed app" : "Remix app");
|
|
5891
6021
|
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.");
|
|
5892
|
-
return /* @__PURE__ */
|
|
6022
|
+
return /* @__PURE__ */ jsx52(
|
|
5893
6023
|
Card,
|
|
5894
6024
|
{
|
|
5895
6025
|
variant: "surfaceRaised",
|
|
@@ -5905,7 +6035,7 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
|
5905
6035
|
style
|
|
5906
6036
|
],
|
|
5907
6037
|
children: /* @__PURE__ */ jsxs30(View40, { style: { minWidth: 0 }, children: [
|
|
5908
|
-
/* @__PURE__ */
|
|
6038
|
+
/* @__PURE__ */ jsx52(
|
|
5909
6039
|
Text,
|
|
5910
6040
|
{
|
|
5911
6041
|
style: {
|
|
@@ -5919,7 +6049,7 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
|
5919
6049
|
children: resolvedTitle
|
|
5920
6050
|
}
|
|
5921
6051
|
),
|
|
5922
|
-
/* @__PURE__ */
|
|
6052
|
+
/* @__PURE__ */ jsx52(
|
|
5923
6053
|
Text,
|
|
5924
6054
|
{
|
|
5925
6055
|
style: {
|
|
@@ -5937,7 +6067,7 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
|
5937
6067
|
}
|
|
5938
6068
|
|
|
5939
6069
|
// src/studio/ui/ChatPanel.tsx
|
|
5940
|
-
import { jsx as
|
|
6070
|
+
import { jsx as jsx53, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
5941
6071
|
function ChatPanel({
|
|
5942
6072
|
title = "Chat",
|
|
5943
6073
|
autoFocusComposer = false,
|
|
@@ -5957,9 +6087,9 @@ function ChatPanel({
|
|
|
5957
6087
|
onStartDraw,
|
|
5958
6088
|
onSend
|
|
5959
6089
|
}) {
|
|
5960
|
-
const listRef =
|
|
5961
|
-
const [nearBottom, setNearBottom] =
|
|
5962
|
-
const handleSend =
|
|
6090
|
+
const listRef = React38.useRef(null);
|
|
6091
|
+
const [nearBottom, setNearBottom] = React38.useState(true);
|
|
6092
|
+
const handleSend = React38.useCallback(
|
|
5963
6093
|
async (text, composerAttachments) => {
|
|
5964
6094
|
const all = composerAttachments ?? attachments;
|
|
5965
6095
|
await onSend(text, all.length > 0 ? all : void 0);
|
|
@@ -5973,25 +6103,25 @@ function ChatPanel({
|
|
|
5973
6103
|
},
|
|
5974
6104
|
[attachments, nearBottom, onClearAttachments, onSend]
|
|
5975
6105
|
);
|
|
5976
|
-
const handleScrollToBottom =
|
|
6106
|
+
const handleScrollToBottom = React38.useCallback(() => {
|
|
5977
6107
|
var _a;
|
|
5978
6108
|
(_a = listRef.current) == null ? void 0 : _a.scrollToBottom({ animated: true });
|
|
5979
6109
|
}, []);
|
|
5980
|
-
const header = /* @__PURE__ */
|
|
6110
|
+
const header = /* @__PURE__ */ jsx53(
|
|
5981
6111
|
ChatHeader,
|
|
5982
6112
|
{
|
|
5983
6113
|
left: /* @__PURE__ */ jsxs31(View41, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5984
|
-
/* @__PURE__ */
|
|
5985
|
-
onNavigateHome ? /* @__PURE__ */
|
|
6114
|
+
/* @__PURE__ */ jsx53(StudioSheetHeaderIconButton, { onPress: onBack, accessibilityLabel: "Back", style: { marginRight: 8 }, children: /* @__PURE__ */ jsx53(IconBack, { size: 20, colorToken: "floatingContent" }) }),
|
|
6115
|
+
onNavigateHome ? /* @__PURE__ */ jsx53(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", children: /* @__PURE__ */ jsx53(IconHome, { size: 20, colorToken: "floatingContent" }) }) : null
|
|
5986
6116
|
] }),
|
|
5987
6117
|
right: /* @__PURE__ */ jsxs31(View41, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5988
|
-
onStartDraw ? /* @__PURE__ */
|
|
5989
|
-
/* @__PURE__ */
|
|
6118
|
+
onStartDraw ? /* @__PURE__ */ jsx53(StudioSheetHeaderIconButton, { onPress: onStartDraw, accessibilityLabel: "Draw", intent: "danger", style: { marginRight: 8 }, children: /* @__PURE__ */ jsx53(IconDraw, { size: 20, colorToken: "onDanger" }) }) : null,
|
|
6119
|
+
/* @__PURE__ */ jsx53(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", children: /* @__PURE__ */ jsx53(IconClose, { size: 20, colorToken: "floatingContent" }) })
|
|
5990
6120
|
] }),
|
|
5991
6121
|
center: null
|
|
5992
6122
|
}
|
|
5993
6123
|
);
|
|
5994
|
-
const topBanner = shouldForkOnEdit ? /* @__PURE__ */
|
|
6124
|
+
const topBanner = shouldForkOnEdit ? /* @__PURE__ */ jsx53(
|
|
5995
6125
|
ForkNoticeBanner,
|
|
5996
6126
|
{
|
|
5997
6127
|
isOwner: !shouldForkOnEdit,
|
|
@@ -6001,31 +6131,32 @@ function ChatPanel({
|
|
|
6001
6131
|
const showMessagesLoading = Boolean(loading) && messages.length === 0 || forking;
|
|
6002
6132
|
if (showMessagesLoading) {
|
|
6003
6133
|
return /* @__PURE__ */ jsxs31(View41, { style: { flex: 1 }, children: [
|
|
6004
|
-
/* @__PURE__ */
|
|
6005
|
-
topBanner ? /* @__PURE__ */
|
|
6134
|
+
/* @__PURE__ */ jsx53(View41, { children: header }),
|
|
6135
|
+
topBanner ? /* @__PURE__ */ jsx53(View41, { style: { paddingHorizontal: 16, paddingTop: 8 }, children: topBanner }) : null,
|
|
6006
6136
|
/* @__PURE__ */ jsxs31(View41, { style: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 24, paddingVertical: 12 }, children: [
|
|
6007
|
-
/* @__PURE__ */
|
|
6008
|
-
/* @__PURE__ */
|
|
6009
|
-
/* @__PURE__ */
|
|
6137
|
+
/* @__PURE__ */ jsx53(ActivityIndicator8, {}),
|
|
6138
|
+
/* @__PURE__ */ jsx53(View41, { style: { height: 12 } }),
|
|
6139
|
+
/* @__PURE__ */ jsx53(Text, { variant: "bodyMuted", children: forking ? "Creating your copy\u2026" : "Loading messages\u2026" })
|
|
6010
6140
|
] })
|
|
6011
6141
|
] });
|
|
6012
6142
|
}
|
|
6013
|
-
return /* @__PURE__ */
|
|
6143
|
+
return /* @__PURE__ */ jsx53(
|
|
6014
6144
|
ChatPage,
|
|
6015
6145
|
{
|
|
6016
6146
|
header,
|
|
6017
6147
|
messages,
|
|
6018
6148
|
showTypingIndicator,
|
|
6019
6149
|
topBanner,
|
|
6150
|
+
composerHorizontalPadding: 0,
|
|
6020
6151
|
listRef,
|
|
6021
6152
|
onNearBottomChange: setNearBottom,
|
|
6022
|
-
overlay: /* @__PURE__ */
|
|
6153
|
+
overlay: /* @__PURE__ */ jsx53(
|
|
6023
6154
|
ScrollToBottomButton,
|
|
6024
6155
|
{
|
|
6025
6156
|
visible: !nearBottom,
|
|
6026
6157
|
onPress: handleScrollToBottom,
|
|
6027
6158
|
style: { bottom: 80 },
|
|
6028
|
-
children: /* @__PURE__ */
|
|
6159
|
+
children: /* @__PURE__ */ jsx53(IconArrowDown, { size: 20, colorToken: "floatingContent" })
|
|
6029
6160
|
}
|
|
6030
6161
|
),
|
|
6031
6162
|
composer: {
|
|
@@ -6046,7 +6177,7 @@ function ChatPanel({
|
|
|
6046
6177
|
}
|
|
6047
6178
|
|
|
6048
6179
|
// src/components/dialogs/ConfirmMergeRequestDialog.tsx
|
|
6049
|
-
import * as
|
|
6180
|
+
import * as React39 from "react";
|
|
6050
6181
|
import { Pressable as Pressable14, View as View43 } from "react-native";
|
|
6051
6182
|
|
|
6052
6183
|
// src/components/primitives/Modal.tsx
|
|
@@ -6055,7 +6186,7 @@ import {
|
|
|
6055
6186
|
Pressable as Pressable13,
|
|
6056
6187
|
View as View42
|
|
6057
6188
|
} from "react-native";
|
|
6058
|
-
import { jsx as
|
|
6189
|
+
import { jsx as jsx54, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
6059
6190
|
function Modal({
|
|
6060
6191
|
visible,
|
|
6061
6192
|
onRequestClose,
|
|
@@ -6064,7 +6195,7 @@ function Modal({
|
|
|
6064
6195
|
contentStyle
|
|
6065
6196
|
}) {
|
|
6066
6197
|
const theme = useTheme();
|
|
6067
|
-
return /* @__PURE__ */
|
|
6198
|
+
return /* @__PURE__ */ jsx54(
|
|
6068
6199
|
RNModal,
|
|
6069
6200
|
{
|
|
6070
6201
|
visible,
|
|
@@ -6072,7 +6203,7 @@ function Modal({
|
|
|
6072
6203
|
animationType: "fade",
|
|
6073
6204
|
onRequestClose,
|
|
6074
6205
|
children: /* @__PURE__ */ jsxs32(View42, { style: { flex: 1, backgroundColor: theme.colors.backdrop, justifyContent: "center", padding: theme.spacing.lg }, children: [
|
|
6075
|
-
/* @__PURE__ */
|
|
6206
|
+
/* @__PURE__ */ jsx54(
|
|
6076
6207
|
Pressable13,
|
|
6077
6208
|
{
|
|
6078
6209
|
accessibilityRole: "button",
|
|
@@ -6080,14 +6211,14 @@ function Modal({
|
|
|
6080
6211
|
style: { position: "absolute", inset: 0 }
|
|
6081
6212
|
}
|
|
6082
6213
|
),
|
|
6083
|
-
/* @__PURE__ */
|
|
6214
|
+
/* @__PURE__ */ jsx54(Card, { variant: "surfaceRaised", padded: true, style: [{ borderRadius: theme.radii.xl }, contentStyle], children })
|
|
6084
6215
|
] })
|
|
6085
6216
|
}
|
|
6086
6217
|
);
|
|
6087
6218
|
}
|
|
6088
6219
|
|
|
6089
6220
|
// src/components/dialogs/ConfirmMergeRequestDialog.tsx
|
|
6090
|
-
import { jsx as
|
|
6221
|
+
import { jsx as jsx55, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
6091
6222
|
function ConfirmMergeRequestDialog({
|
|
6092
6223
|
visible,
|
|
6093
6224
|
onOpenChange,
|
|
@@ -6098,14 +6229,14 @@ function ConfirmMergeRequestDialog({
|
|
|
6098
6229
|
onTestFirst
|
|
6099
6230
|
}) {
|
|
6100
6231
|
const theme = useTheme();
|
|
6101
|
-
const close =
|
|
6232
|
+
const close = React39.useCallback(() => onOpenChange(false), [onOpenChange]);
|
|
6102
6233
|
const canConfirm = Boolean(mergeRequest) && !approveDisabled;
|
|
6103
|
-
const handleConfirm =
|
|
6234
|
+
const handleConfirm = React39.useCallback(() => {
|
|
6104
6235
|
if (!mergeRequest) return;
|
|
6105
6236
|
onOpenChange(false);
|
|
6106
6237
|
void onConfirm();
|
|
6107
6238
|
}, [mergeRequest, onConfirm, onOpenChange]);
|
|
6108
|
-
const handleTestFirst =
|
|
6239
|
+
const handleTestFirst = React39.useCallback(() => {
|
|
6109
6240
|
if (!mergeRequest) return;
|
|
6110
6241
|
onOpenChange(false);
|
|
6111
6242
|
void onTestFirst(mergeRequest);
|
|
@@ -6128,7 +6259,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6128
6259
|
backgroundColor: theme.colors.background
|
|
6129
6260
|
},
|
|
6130
6261
|
children: [
|
|
6131
|
-
/* @__PURE__ */
|
|
6262
|
+
/* @__PURE__ */ jsx55(View43, { children: /* @__PURE__ */ jsx55(
|
|
6132
6263
|
Text,
|
|
6133
6264
|
{
|
|
6134
6265
|
style: {
|
|
@@ -6141,7 +6272,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6141
6272
|
}
|
|
6142
6273
|
) }),
|
|
6143
6274
|
/* @__PURE__ */ jsxs33(View43, { style: { marginTop: 16 }, children: [
|
|
6144
|
-
/* @__PURE__ */
|
|
6275
|
+
/* @__PURE__ */ jsx55(
|
|
6145
6276
|
View43,
|
|
6146
6277
|
{
|
|
6147
6278
|
style: [
|
|
@@ -6151,7 +6282,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6151
6282
|
opacity: canConfirm ? 1 : 0.5
|
|
6152
6283
|
}
|
|
6153
6284
|
],
|
|
6154
|
-
children: /* @__PURE__ */
|
|
6285
|
+
children: /* @__PURE__ */ jsx55(
|
|
6155
6286
|
Pressable14,
|
|
6156
6287
|
{
|
|
6157
6288
|
accessibilityRole: "button",
|
|
@@ -6159,13 +6290,13 @@ function ConfirmMergeRequestDialog({
|
|
|
6159
6290
|
disabled: !canConfirm,
|
|
6160
6291
|
onPress: handleConfirm,
|
|
6161
6292
|
style: [fullWidthButtonBase, { flex: 1 }],
|
|
6162
|
-
children: /* @__PURE__ */
|
|
6293
|
+
children: /* @__PURE__ */ jsx55(Text, { style: { textAlign: "center", color: theme.colors.onPrimary }, children: "Approve Merge" })
|
|
6163
6294
|
}
|
|
6164
6295
|
)
|
|
6165
6296
|
}
|
|
6166
6297
|
),
|
|
6167
|
-
/* @__PURE__ */
|
|
6168
|
-
/* @__PURE__ */
|
|
6298
|
+
/* @__PURE__ */ jsx55(View43, { style: { height: 8 } }),
|
|
6299
|
+
/* @__PURE__ */ jsx55(
|
|
6169
6300
|
View43,
|
|
6170
6301
|
{
|
|
6171
6302
|
style: [
|
|
@@ -6177,7 +6308,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6177
6308
|
opacity: isBuilding || !mergeRequest ? 0.5 : 1
|
|
6178
6309
|
}
|
|
6179
6310
|
],
|
|
6180
|
-
children: /* @__PURE__ */
|
|
6311
|
+
children: /* @__PURE__ */ jsx55(
|
|
6181
6312
|
Pressable14,
|
|
6182
6313
|
{
|
|
6183
6314
|
accessibilityRole: "button",
|
|
@@ -6185,13 +6316,13 @@ function ConfirmMergeRequestDialog({
|
|
|
6185
6316
|
disabled: isBuilding || !mergeRequest,
|
|
6186
6317
|
onPress: handleTestFirst,
|
|
6187
6318
|
style: [fullWidthButtonBase, { flex: 1 }],
|
|
6188
|
-
children: /* @__PURE__ */
|
|
6319
|
+
children: /* @__PURE__ */ jsx55(Text, { style: { textAlign: "center", color: theme.colors.text }, children: isBuilding ? "Preparing\u2026" : "Test edits first" })
|
|
6189
6320
|
}
|
|
6190
6321
|
)
|
|
6191
6322
|
}
|
|
6192
6323
|
),
|
|
6193
|
-
/* @__PURE__ */
|
|
6194
|
-
/* @__PURE__ */
|
|
6324
|
+
/* @__PURE__ */ jsx55(View43, { style: { height: 8 } }),
|
|
6325
|
+
/* @__PURE__ */ jsx55(
|
|
6195
6326
|
View43,
|
|
6196
6327
|
{
|
|
6197
6328
|
style: [
|
|
@@ -6202,14 +6333,14 @@ function ConfirmMergeRequestDialog({
|
|
|
6202
6333
|
borderColor: theme.colors.border
|
|
6203
6334
|
}
|
|
6204
6335
|
],
|
|
6205
|
-
children: /* @__PURE__ */
|
|
6336
|
+
children: /* @__PURE__ */ jsx55(
|
|
6206
6337
|
Pressable14,
|
|
6207
6338
|
{
|
|
6208
6339
|
accessibilityRole: "button",
|
|
6209
6340
|
accessibilityLabel: "Cancel",
|
|
6210
6341
|
onPress: close,
|
|
6211
6342
|
style: [fullWidthButtonBase, { flex: 1 }],
|
|
6212
|
-
children: /* @__PURE__ */
|
|
6343
|
+
children: /* @__PURE__ */ jsx55(Text, { style: { textAlign: "center", color: theme.colors.text }, children: "Cancel" })
|
|
6213
6344
|
}
|
|
6214
6345
|
)
|
|
6215
6346
|
}
|
|
@@ -6221,7 +6352,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6221
6352
|
}
|
|
6222
6353
|
|
|
6223
6354
|
// src/studio/ui/ConfirmMergeFlow.tsx
|
|
6224
|
-
import { jsx as
|
|
6355
|
+
import { jsx as jsx56 } from "react/jsx-runtime";
|
|
6225
6356
|
function ConfirmMergeFlow({
|
|
6226
6357
|
visible,
|
|
6227
6358
|
onOpenChange,
|
|
@@ -6232,7 +6363,7 @@ function ConfirmMergeFlow({
|
|
|
6232
6363
|
onConfirm,
|
|
6233
6364
|
onTestFirst
|
|
6234
6365
|
}) {
|
|
6235
|
-
return /* @__PURE__ */
|
|
6366
|
+
return /* @__PURE__ */ jsx56(
|
|
6236
6367
|
ConfirmMergeRequestDialog,
|
|
6237
6368
|
{
|
|
6238
6369
|
visible,
|
|
@@ -6253,8 +6384,94 @@ function ConfirmMergeFlow({
|
|
|
6253
6384
|
);
|
|
6254
6385
|
}
|
|
6255
6386
|
|
|
6387
|
+
// src/studio/hooks/useOptimisticChatMessages.ts
|
|
6388
|
+
import * as React40 from "react";
|
|
6389
|
+
function makeOptimisticId() {
|
|
6390
|
+
return `optimistic:${Date.now().toString(36)}:${Math.random().toString(36).slice(2, 10)}`;
|
|
6391
|
+
}
|
|
6392
|
+
function toEpochMs(createdAt) {
|
|
6393
|
+
if (createdAt == null) return 0;
|
|
6394
|
+
if (typeof createdAt === "number") return createdAt;
|
|
6395
|
+
if (createdAt instanceof Date) return createdAt.getTime();
|
|
6396
|
+
const t = Date.parse(String(createdAt));
|
|
6397
|
+
return Number.isFinite(t) ? t : 0;
|
|
6398
|
+
}
|
|
6399
|
+
function isOptimisticResolvedByServer(chatMessages, o) {
|
|
6400
|
+
if (o.failed) return false;
|
|
6401
|
+
const normalize = (s) => s.trim();
|
|
6402
|
+
let startIndex = -1;
|
|
6403
|
+
if (o.baseServerLastId) {
|
|
6404
|
+
startIndex = chatMessages.findIndex((m) => m.id === o.baseServerLastId);
|
|
6405
|
+
}
|
|
6406
|
+
const candidates = startIndex >= 0 ? chatMessages.slice(startIndex + 1) : chatMessages;
|
|
6407
|
+
const target = normalize(o.content);
|
|
6408
|
+
for (const m of candidates) {
|
|
6409
|
+
if (m.author !== "human") continue;
|
|
6410
|
+
if (normalize(m.content) !== target) continue;
|
|
6411
|
+
const serverMs = toEpochMs(m.createdAt);
|
|
6412
|
+
const optimisticMs = Date.parse(o.createdAtIso);
|
|
6413
|
+
if (Number.isFinite(optimisticMs) && optimisticMs > 0 && serverMs > 0) {
|
|
6414
|
+
if (serverMs + 12e4 < optimisticMs) continue;
|
|
6415
|
+
}
|
|
6416
|
+
return true;
|
|
6417
|
+
}
|
|
6418
|
+
return false;
|
|
6419
|
+
}
|
|
6420
|
+
function useOptimisticChatMessages({
|
|
6421
|
+
threadId,
|
|
6422
|
+
shouldForkOnEdit,
|
|
6423
|
+
chatMessages,
|
|
6424
|
+
onSendChat
|
|
6425
|
+
}) {
|
|
6426
|
+
const [optimisticChat, setOptimisticChat] = React40.useState([]);
|
|
6427
|
+
React40.useEffect(() => {
|
|
6428
|
+
setOptimisticChat([]);
|
|
6429
|
+
}, [threadId]);
|
|
6430
|
+
const messages = React40.useMemo(() => {
|
|
6431
|
+
if (!optimisticChat || optimisticChat.length === 0) return chatMessages;
|
|
6432
|
+
const unresolved = optimisticChat.filter((o) => !isOptimisticResolvedByServer(chatMessages, o));
|
|
6433
|
+
if (unresolved.length === 0) return chatMessages;
|
|
6434
|
+
const optimisticAsChat = unresolved.map((o) => ({
|
|
6435
|
+
id: o.id,
|
|
6436
|
+
author: "human",
|
|
6437
|
+
content: o.content,
|
|
6438
|
+
createdAt: o.createdAtIso,
|
|
6439
|
+
kind: "optimistic",
|
|
6440
|
+
meta: o.failed ? { kind: "optimistic", event: "send.failed", status: "error" } : { kind: "optimistic", event: "send.pending", status: "info" }
|
|
6441
|
+
}));
|
|
6442
|
+
const merged = [...chatMessages, ...optimisticAsChat];
|
|
6443
|
+
merged.sort((a, b) => String(a.createdAt).localeCompare(String(b.createdAt)));
|
|
6444
|
+
return merged;
|
|
6445
|
+
}, [chatMessages, optimisticChat]);
|
|
6446
|
+
React40.useEffect(() => {
|
|
6447
|
+
if (optimisticChat.length === 0) return;
|
|
6448
|
+
setOptimisticChat((prev) => {
|
|
6449
|
+
if (prev.length === 0) return prev;
|
|
6450
|
+
const next = prev.filter((o) => !isOptimisticResolvedByServer(chatMessages, o) || o.failed);
|
|
6451
|
+
return next.length === prev.length ? prev : next;
|
|
6452
|
+
});
|
|
6453
|
+
}, [chatMessages, optimisticChat.length]);
|
|
6454
|
+
const onSend = React40.useCallback(
|
|
6455
|
+
async (text, attachments) => {
|
|
6456
|
+
if (shouldForkOnEdit) {
|
|
6457
|
+
await onSendChat(text, attachments);
|
|
6458
|
+
return;
|
|
6459
|
+
}
|
|
6460
|
+
const createdAtIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
6461
|
+
const baseServerLastId = chatMessages.length > 0 ? chatMessages[chatMessages.length - 1].id : null;
|
|
6462
|
+
const id = makeOptimisticId();
|
|
6463
|
+
setOptimisticChat((prev) => [...prev, { id, content: text, createdAtIso, baseServerLastId, failed: false }]);
|
|
6464
|
+
void Promise.resolve(onSendChat(text, attachments)).catch(() => {
|
|
6465
|
+
setOptimisticChat((prev) => prev.map((m) => m.id === id ? { ...m, failed: true } : m));
|
|
6466
|
+
});
|
|
6467
|
+
},
|
|
6468
|
+
[chatMessages, onSendChat, shouldForkOnEdit]
|
|
6469
|
+
);
|
|
6470
|
+
return { messages, onSend };
|
|
6471
|
+
}
|
|
6472
|
+
|
|
6256
6473
|
// src/studio/ui/StudioOverlay.tsx
|
|
6257
|
-
import { Fragment as Fragment6, jsx as
|
|
6474
|
+
import { Fragment as Fragment6, jsx as jsx57, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
6258
6475
|
function StudioOverlay({
|
|
6259
6476
|
captureTargetRef,
|
|
6260
6477
|
app,
|
|
@@ -6285,31 +6502,38 @@ function StudioOverlay({
|
|
|
6285
6502
|
}) {
|
|
6286
6503
|
const theme = useTheme();
|
|
6287
6504
|
const { width } = useWindowDimensions4();
|
|
6288
|
-
const [sheetOpen, setSheetOpen] =
|
|
6289
|
-
const [activePage, setActivePage] =
|
|
6290
|
-
const [drawing, setDrawing] =
|
|
6291
|
-
const [chatAttachments, setChatAttachments] =
|
|
6292
|
-
const [commentsAppId, setCommentsAppId] =
|
|
6293
|
-
const [commentsCount, setCommentsCount] =
|
|
6294
|
-
const
|
|
6295
|
-
const
|
|
6505
|
+
const [sheetOpen, setSheetOpen] = React41.useState(false);
|
|
6506
|
+
const [activePage, setActivePage] = React41.useState("preview");
|
|
6507
|
+
const [drawing, setDrawing] = React41.useState(false);
|
|
6508
|
+
const [chatAttachments, setChatAttachments] = React41.useState([]);
|
|
6509
|
+
const [commentsAppId, setCommentsAppId] = React41.useState(null);
|
|
6510
|
+
const [commentsCount, setCommentsCount] = React41.useState(null);
|
|
6511
|
+
const threadId = (app == null ? void 0 : app.threadId) ?? null;
|
|
6512
|
+
const optimistic = useOptimisticChatMessages({
|
|
6513
|
+
threadId,
|
|
6514
|
+
shouldForkOnEdit,
|
|
6515
|
+
chatMessages,
|
|
6516
|
+
onSendChat
|
|
6517
|
+
});
|
|
6518
|
+
const [confirmMrId, setConfirmMrId] = React41.useState(null);
|
|
6519
|
+
const confirmMr = React41.useMemo(
|
|
6296
6520
|
() => confirmMrId ? incomingMergeRequests.find((m) => m.id === confirmMrId) ?? null : null,
|
|
6297
6521
|
[confirmMrId, incomingMergeRequests]
|
|
6298
6522
|
);
|
|
6299
|
-
const handleSheetOpenChange =
|
|
6523
|
+
const handleSheetOpenChange = React41.useCallback((open) => {
|
|
6300
6524
|
setSheetOpen(open);
|
|
6301
6525
|
if (!open) Keyboard5.dismiss();
|
|
6302
6526
|
}, []);
|
|
6303
|
-
const closeSheet =
|
|
6527
|
+
const closeSheet = React41.useCallback(() => {
|
|
6304
6528
|
handleSheetOpenChange(false);
|
|
6305
6529
|
}, [handleSheetOpenChange]);
|
|
6306
|
-
const openSheet =
|
|
6307
|
-
const goToChat =
|
|
6530
|
+
const openSheet = React41.useCallback(() => setSheetOpen(true), []);
|
|
6531
|
+
const goToChat = React41.useCallback(() => {
|
|
6308
6532
|
setActivePage("chat");
|
|
6309
6533
|
openSheet();
|
|
6310
6534
|
}, [openSheet]);
|
|
6311
|
-
const backToPreview =
|
|
6312
|
-
if (
|
|
6535
|
+
const backToPreview = React41.useCallback(() => {
|
|
6536
|
+
if (Platform10.OS !== "ios") {
|
|
6313
6537
|
Keyboard5.dismiss();
|
|
6314
6538
|
setActivePage("preview");
|
|
6315
6539
|
return;
|
|
@@ -6326,11 +6550,11 @@ function StudioOverlay({
|
|
|
6326
6550
|
const t = setTimeout(finalize, 350);
|
|
6327
6551
|
Keyboard5.dismiss();
|
|
6328
6552
|
}, []);
|
|
6329
|
-
const startDraw =
|
|
6553
|
+
const startDraw = React41.useCallback(() => {
|
|
6330
6554
|
setDrawing(true);
|
|
6331
6555
|
closeSheet();
|
|
6332
6556
|
}, [closeSheet]);
|
|
6333
|
-
const handleDrawCapture =
|
|
6557
|
+
const handleDrawCapture = React41.useCallback(
|
|
6334
6558
|
(dataUrl) => {
|
|
6335
6559
|
setChatAttachments((prev) => [...prev, dataUrl]);
|
|
6336
6560
|
setDrawing(false);
|
|
@@ -6339,7 +6563,7 @@ function StudioOverlay({
|
|
|
6339
6563
|
},
|
|
6340
6564
|
[openSheet]
|
|
6341
6565
|
);
|
|
6342
|
-
const toggleSheet =
|
|
6566
|
+
const toggleSheet = React41.useCallback(async () => {
|
|
6343
6567
|
if (!sheetOpen) {
|
|
6344
6568
|
const shouldExitTest = Boolean(testingMrId) || isTesting;
|
|
6345
6569
|
if (shouldExitTest) {
|
|
@@ -6351,7 +6575,7 @@ function StudioOverlay({
|
|
|
6351
6575
|
closeSheet();
|
|
6352
6576
|
}
|
|
6353
6577
|
}, [closeSheet, isTesting, onRestoreBase, sheetOpen, testingMrId]);
|
|
6354
|
-
const handleTestMr =
|
|
6578
|
+
const handleTestMr = React41.useCallback(
|
|
6355
6579
|
async (mr) => {
|
|
6356
6580
|
if (!onTestMr) return;
|
|
6357
6581
|
await onTestMr(mr);
|
|
@@ -6360,13 +6584,13 @@ function StudioOverlay({
|
|
|
6360
6584
|
[closeSheet, onTestMr]
|
|
6361
6585
|
);
|
|
6362
6586
|
return /* @__PURE__ */ jsxs34(Fragment6, { children: [
|
|
6363
|
-
/* @__PURE__ */
|
|
6364
|
-
/* @__PURE__ */
|
|
6587
|
+
/* @__PURE__ */ jsx57(EdgeGlowFrame, { visible: isTesting, role: "accent", thickness: 40, intensity: 1 }),
|
|
6588
|
+
/* @__PURE__ */ jsx57(StudioBottomSheet, { open: sheetOpen, onOpenChange: handleSheetOpenChange, children: /* @__PURE__ */ jsx57(
|
|
6365
6589
|
StudioSheetPager,
|
|
6366
6590
|
{
|
|
6367
6591
|
activePage,
|
|
6368
6592
|
width,
|
|
6369
|
-
preview: /* @__PURE__ */
|
|
6593
|
+
preview: /* @__PURE__ */ jsx57(
|
|
6370
6594
|
PreviewPanel,
|
|
6371
6595
|
{
|
|
6372
6596
|
app,
|
|
@@ -6392,10 +6616,10 @@ function StudioOverlay({
|
|
|
6392
6616
|
commentCountOverride: commentsCount ?? void 0
|
|
6393
6617
|
}
|
|
6394
6618
|
),
|
|
6395
|
-
chat: /* @__PURE__ */
|
|
6619
|
+
chat: /* @__PURE__ */ jsx57(
|
|
6396
6620
|
ChatPanel,
|
|
6397
6621
|
{
|
|
6398
|
-
messages:
|
|
6622
|
+
messages: optimistic.messages,
|
|
6399
6623
|
showTypingIndicator: chatShowTypingIndicator,
|
|
6400
6624
|
loading: chatLoading,
|
|
6401
6625
|
sendDisabled: chatSendDisabled,
|
|
@@ -6410,12 +6634,12 @@ function StudioOverlay({
|
|
|
6410
6634
|
onClose: closeSheet,
|
|
6411
6635
|
onNavigateHome,
|
|
6412
6636
|
onStartDraw: startDraw,
|
|
6413
|
-
onSend:
|
|
6637
|
+
onSend: optimistic.onSend
|
|
6414
6638
|
}
|
|
6415
6639
|
)
|
|
6416
6640
|
}
|
|
6417
6641
|
) }),
|
|
6418
|
-
/* @__PURE__ */
|
|
6642
|
+
/* @__PURE__ */ jsx57(
|
|
6419
6643
|
FloatingDraggableButton,
|
|
6420
6644
|
{
|
|
6421
6645
|
visible: !sheetOpen && !drawing,
|
|
@@ -6423,10 +6647,10 @@ function StudioOverlay({
|
|
|
6423
6647
|
badgeCount: incomingMergeRequests.length,
|
|
6424
6648
|
onPress: toggleSheet,
|
|
6425
6649
|
isLoading: (app == null ? void 0 : app.status) === "editing",
|
|
6426
|
-
children: /* @__PURE__ */
|
|
6650
|
+
children: /* @__PURE__ */ jsx57(View44, { style: { width: 28, height: 28, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx57(MergeIcon, { width: 24, height: 24, color: theme.colors.floatingContent }) })
|
|
6427
6651
|
}
|
|
6428
6652
|
),
|
|
6429
|
-
/* @__PURE__ */
|
|
6653
|
+
/* @__PURE__ */ jsx57(
|
|
6430
6654
|
DrawModeOverlay,
|
|
6431
6655
|
{
|
|
6432
6656
|
visible: drawing,
|
|
@@ -6435,7 +6659,7 @@ function StudioOverlay({
|
|
|
6435
6659
|
onCapture: handleDrawCapture
|
|
6436
6660
|
}
|
|
6437
6661
|
),
|
|
6438
|
-
/* @__PURE__ */
|
|
6662
|
+
/* @__PURE__ */ jsx57(
|
|
6439
6663
|
ConfirmMergeFlow,
|
|
6440
6664
|
{
|
|
6441
6665
|
visible: Boolean(confirmMr),
|
|
@@ -6448,7 +6672,7 @@ function StudioOverlay({
|
|
|
6448
6672
|
onTestFirst: handleTestMr
|
|
6449
6673
|
}
|
|
6450
6674
|
),
|
|
6451
|
-
/* @__PURE__ */
|
|
6675
|
+
/* @__PURE__ */ jsx57(
|
|
6452
6676
|
AppCommentsSheet,
|
|
6453
6677
|
{
|
|
6454
6678
|
appId: commentsAppId,
|
|
@@ -6461,7 +6685,7 @@ function StudioOverlay({
|
|
|
6461
6685
|
}
|
|
6462
6686
|
|
|
6463
6687
|
// src/studio/ComergeStudio.tsx
|
|
6464
|
-
import { jsx as
|
|
6688
|
+
import { jsx as jsx58, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
6465
6689
|
function ComergeStudio({
|
|
6466
6690
|
appId,
|
|
6467
6691
|
apiKey,
|
|
@@ -6469,17 +6693,17 @@ function ComergeStudio({
|
|
|
6469
6693
|
onNavigateHome,
|
|
6470
6694
|
style
|
|
6471
6695
|
}) {
|
|
6472
|
-
const [activeAppId, setActiveAppId] =
|
|
6473
|
-
const [runtimeAppId, setRuntimeAppId] =
|
|
6474
|
-
const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] =
|
|
6475
|
-
const platform =
|
|
6476
|
-
|
|
6696
|
+
const [activeAppId, setActiveAppId] = React42.useState(appId);
|
|
6697
|
+
const [runtimeAppId, setRuntimeAppId] = React42.useState(appId);
|
|
6698
|
+
const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] = React42.useState(null);
|
|
6699
|
+
const platform = React42.useMemo(() => RNPlatform.OS === "ios" ? "ios" : "android", []);
|
|
6700
|
+
React42.useEffect(() => {
|
|
6477
6701
|
setActiveAppId(appId);
|
|
6478
6702
|
setRuntimeAppId(appId);
|
|
6479
6703
|
setPendingRuntimeTargetAppId(null);
|
|
6480
6704
|
}, [appId]);
|
|
6481
|
-
const captureTargetRef =
|
|
6482
|
-
return /* @__PURE__ */
|
|
6705
|
+
const captureTargetRef = React42.useRef(null);
|
|
6706
|
+
return /* @__PURE__ */ jsx58(StudioBootstrap, { apiKey, children: ({ userId }) => /* @__PURE__ */ jsx58(BottomSheetModalProvider, { children: /* @__PURE__ */ jsx58(LiquidGlassResetProvider, { resetTriggers: [appId, activeAppId, runtimeAppId], children: /* @__PURE__ */ jsx58(
|
|
6483
6707
|
ComergeStudioInner,
|
|
6484
6708
|
{
|
|
6485
6709
|
userId,
|
|
@@ -6495,7 +6719,7 @@ function ComergeStudio({
|
|
|
6495
6719
|
captureTargetRef,
|
|
6496
6720
|
style
|
|
6497
6721
|
}
|
|
6498
|
-
) }) });
|
|
6722
|
+
) }) }) });
|
|
6499
6723
|
}
|
|
6500
6724
|
function ComergeStudioInner({
|
|
6501
6725
|
userId,
|
|
@@ -6514,11 +6738,11 @@ function ComergeStudioInner({
|
|
|
6514
6738
|
const { app, loading: appLoading } = useApp(activeAppId);
|
|
6515
6739
|
const { app: runtimeAppFromHook } = useApp(runtimeAppId, { enabled: runtimeAppId !== activeAppId });
|
|
6516
6740
|
const runtimeApp = runtimeAppId === activeAppId ? app : runtimeAppFromHook;
|
|
6517
|
-
const sawEditingOnPendingTargetRef =
|
|
6518
|
-
|
|
6741
|
+
const sawEditingOnPendingTargetRef = React42.useRef(false);
|
|
6742
|
+
React42.useEffect(() => {
|
|
6519
6743
|
sawEditingOnPendingTargetRef.current = false;
|
|
6520
6744
|
}, [pendingRuntimeTargetAppId]);
|
|
6521
|
-
|
|
6745
|
+
React42.useEffect(() => {
|
|
6522
6746
|
if (!pendingRuntimeTargetAppId) return;
|
|
6523
6747
|
if (activeAppId !== pendingRuntimeTargetAppId) return;
|
|
6524
6748
|
if ((app == null ? void 0 : app.status) === "editing") {
|
|
@@ -6535,13 +6759,38 @@ function ComergeStudioInner({
|
|
|
6535
6759
|
platform,
|
|
6536
6760
|
canRequestLatest: (runtimeApp == null ? void 0 : runtimeApp.status) === "ready"
|
|
6537
6761
|
});
|
|
6762
|
+
const sawEditingOnActiveAppRef = React42.useRef(false);
|
|
6763
|
+
const [showPostEditPreparing, setShowPostEditPreparing] = React42.useState(false);
|
|
6764
|
+
React42.useEffect(() => {
|
|
6765
|
+
sawEditingOnActiveAppRef.current = false;
|
|
6766
|
+
setShowPostEditPreparing(false);
|
|
6767
|
+
}, [activeAppId]);
|
|
6768
|
+
React42.useEffect(() => {
|
|
6769
|
+
if (!(app == null ? void 0 : app.id)) return;
|
|
6770
|
+
if (app.status === "editing") {
|
|
6771
|
+
sawEditingOnActiveAppRef.current = true;
|
|
6772
|
+
setShowPostEditPreparing(false);
|
|
6773
|
+
return;
|
|
6774
|
+
}
|
|
6775
|
+
if (app.status === "ready" && sawEditingOnActiveAppRef.current) {
|
|
6776
|
+
setShowPostEditPreparing(true);
|
|
6777
|
+
sawEditingOnActiveAppRef.current = false;
|
|
6778
|
+
}
|
|
6779
|
+
}, [app == null ? void 0 : app.id, app == null ? void 0 : app.status]);
|
|
6780
|
+
React42.useEffect(() => {
|
|
6781
|
+
if (!showPostEditPreparing) return;
|
|
6782
|
+
const stillProcessingBaseBundle = bundle.loading && bundle.loadingMode === "base" && !bundle.isTesting;
|
|
6783
|
+
if (!stillProcessingBaseBundle) {
|
|
6784
|
+
setShowPostEditPreparing(false);
|
|
6785
|
+
}
|
|
6786
|
+
}, [showPostEditPreparing, bundle.loading, bundle.loadingMode, bundle.isTesting]);
|
|
6538
6787
|
const threadId = (app == null ? void 0 : app.threadId) ?? "";
|
|
6539
6788
|
const thread = useThreadMessages(threadId);
|
|
6540
6789
|
const mergeRequests = useMergeRequests({ appId: activeAppId });
|
|
6541
|
-
const hasOpenOutgoingMr =
|
|
6790
|
+
const hasOpenOutgoingMr = React42.useMemo(() => {
|
|
6542
6791
|
return mergeRequests.lists.outgoing.some((mr) => mr.status === "open");
|
|
6543
6792
|
}, [mergeRequests.lists.outgoing]);
|
|
6544
|
-
const incomingReviewMrs =
|
|
6793
|
+
const incomingReviewMrs = React42.useMemo(() => {
|
|
6545
6794
|
if (!userId) return mergeRequests.lists.incoming;
|
|
6546
6795
|
return mergeRequests.lists.incoming.filter((mr) => mr.createdBy !== userId);
|
|
6547
6796
|
}, [mergeRequests.lists.incoming, userId]);
|
|
@@ -6563,18 +6812,26 @@ function ComergeStudioInner({
|
|
|
6563
6812
|
uploadAttachments: uploader.uploadBase64Images
|
|
6564
6813
|
});
|
|
6565
6814
|
const chatSendDisabled = hasNoOutcomeAfterLastHuman(thread.raw);
|
|
6566
|
-
const [processingMrId, setProcessingMrId] =
|
|
6567
|
-
const [testingMrId, setTestingMrId] =
|
|
6568
|
-
const chatShowTypingIndicator =
|
|
6815
|
+
const [processingMrId, setProcessingMrId] = React42.useState(null);
|
|
6816
|
+
const [testingMrId, setTestingMrId] = React42.useState(null);
|
|
6817
|
+
const chatShowTypingIndicator = React42.useMemo(() => {
|
|
6569
6818
|
var _a;
|
|
6570
6819
|
if (!thread.raw || thread.raw.length === 0) return false;
|
|
6571
6820
|
const last = thread.raw[thread.raw.length - 1];
|
|
6572
6821
|
const payloadType = typeof ((_a = last.payload) == null ? void 0 : _a.type) === "string" ? String(last.payload.type) : void 0;
|
|
6573
6822
|
return payloadType !== "outcome";
|
|
6574
6823
|
}, [thread.raw]);
|
|
6575
|
-
return /* @__PURE__ */
|
|
6576
|
-
/* @__PURE__ */
|
|
6577
|
-
|
|
6824
|
+
return /* @__PURE__ */ jsx58(View45, { style: [{ flex: 1 }, style], children: /* @__PURE__ */ jsxs35(View45, { ref: captureTargetRef, style: { flex: 1 }, collapsable: false, children: [
|
|
6825
|
+
/* @__PURE__ */ jsx58(
|
|
6826
|
+
RuntimeRenderer,
|
|
6827
|
+
{
|
|
6828
|
+
appKey,
|
|
6829
|
+
bundlePath: bundle.bundlePath,
|
|
6830
|
+
forcePreparing: showPostEditPreparing,
|
|
6831
|
+
renderToken: bundle.renderToken
|
|
6832
|
+
}
|
|
6833
|
+
),
|
|
6834
|
+
/* @__PURE__ */ jsx58(
|
|
6578
6835
|
StudioOverlay,
|
|
6579
6836
|
{
|
|
6580
6837
|
captureTargetRef,
|