@comergehq/studio 0.1.9 → 0.1.10
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 +608 -386
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +328 -106
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/chat/ChatMessageList.tsx +21 -35
- package/src/components/chat/ChatPage.tsx +3 -1
- package/src/components/studio-sheet/StudioBottomSheet.tsx +3 -3
- package/src/studio/ComergeStudio.tsx +34 -1
- 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.js
CHANGED
|
@@ -36,8 +36,8 @@ __export(index_exports, {
|
|
|
36
36
|
module.exports = __toCommonJS(index_exports);
|
|
37
37
|
|
|
38
38
|
// src/studio/ComergeStudio.tsx
|
|
39
|
-
var
|
|
40
|
-
var
|
|
39
|
+
var React40 = __toESM(require("react"));
|
|
40
|
+
var import_react_native54 = require("react-native");
|
|
41
41
|
var import_bottom_sheet6 = require("@gorhom/bottom-sheet");
|
|
42
42
|
|
|
43
43
|
// src/studio/bootstrap/StudioBootstrap.tsx
|
|
@@ -982,6 +982,39 @@ var BundlesRepositoryImpl = class extends BaseRepository {
|
|
|
982
982
|
var bundlesRepository = new BundlesRepositoryImpl(bundlesRemoteDataSource);
|
|
983
983
|
|
|
984
984
|
// src/studio/hooks/useBundleManager.ts
|
|
985
|
+
function sleep(ms) {
|
|
986
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
987
|
+
}
|
|
988
|
+
function isRetryableNetworkError(e) {
|
|
989
|
+
var _a;
|
|
990
|
+
const err = e;
|
|
991
|
+
const code = typeof (err == null ? void 0 : err.code) === "string" ? err.code : "";
|
|
992
|
+
const message = typeof (err == null ? void 0 : err.message) === "string" ? err.message : "";
|
|
993
|
+
if (code === "ERR_NETWORK" || code === "ECONNABORTED") return true;
|
|
994
|
+
if (message.toLowerCase().includes("network error")) return true;
|
|
995
|
+
if (message.toLowerCase().includes("timeout")) return true;
|
|
996
|
+
const status = typeof ((_a = err == null ? void 0 : err.response) == null ? void 0 : _a.status) === "number" ? err.response.status : void 0;
|
|
997
|
+
if (status && (status === 429 || status >= 500)) return true;
|
|
998
|
+
return false;
|
|
999
|
+
}
|
|
1000
|
+
async function withRetry(fn, opts) {
|
|
1001
|
+
let lastErr = null;
|
|
1002
|
+
for (let attempt = 1; attempt <= opts.attempts; attempt += 1) {
|
|
1003
|
+
try {
|
|
1004
|
+
return await fn();
|
|
1005
|
+
} catch (e) {
|
|
1006
|
+
lastErr = e;
|
|
1007
|
+
const retryable = isRetryableNetworkError(e);
|
|
1008
|
+
if (!retryable || attempt >= opts.attempts) {
|
|
1009
|
+
throw e;
|
|
1010
|
+
}
|
|
1011
|
+
const exp = Math.min(opts.maxDelayMs, opts.baseDelayMs * Math.pow(2, attempt - 1));
|
|
1012
|
+
const jitter = Math.floor(Math.random() * 250);
|
|
1013
|
+
await sleep(exp + jitter);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
throw lastErr;
|
|
1017
|
+
}
|
|
985
1018
|
function safeName(s) {
|
|
986
1019
|
return s.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
987
1020
|
}
|
|
@@ -1039,8 +1072,16 @@ async function getExistingNonEmptyFileUri(fileUri) {
|
|
|
1039
1072
|
async function downloadIfMissing(url, fileUri) {
|
|
1040
1073
|
const existing = await getExistingNonEmptyFileUri(fileUri);
|
|
1041
1074
|
if (existing) return existing;
|
|
1042
|
-
|
|
1043
|
-
|
|
1075
|
+
return await withRetry(
|
|
1076
|
+
async () => {
|
|
1077
|
+
await deleteFileIfExists(fileUri);
|
|
1078
|
+
const res = await FileSystem.downloadAsync(url, fileUri);
|
|
1079
|
+
const ok = await getExistingNonEmptyFileUri(res.uri);
|
|
1080
|
+
if (!ok) throw new Error("Downloaded bundle is empty.");
|
|
1081
|
+
return res.uri;
|
|
1082
|
+
},
|
|
1083
|
+
{ attempts: 3, baseDelayMs: 500, maxDelayMs: 4e3 }
|
|
1084
|
+
);
|
|
1044
1085
|
}
|
|
1045
1086
|
async function deleteFileIfExists(fileUri) {
|
|
1046
1087
|
try {
|
|
@@ -1054,11 +1095,15 @@ async function deleteFileIfExists(fileUri) {
|
|
|
1054
1095
|
async function safeReplaceFileFromUrl(url, targetUri, tmpKey) {
|
|
1055
1096
|
const tmpUri = toBundleFileUri(`tmp:${tmpKey}:${Date.now()}`);
|
|
1056
1097
|
try {
|
|
1057
|
-
await
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1098
|
+
await withRetry(
|
|
1099
|
+
async () => {
|
|
1100
|
+
await deleteFileIfExists(tmpUri);
|
|
1101
|
+
await FileSystem.downloadAsync(url, tmpUri);
|
|
1102
|
+
const tmpOk = await getExistingNonEmptyFileUri(tmpUri);
|
|
1103
|
+
if (!tmpOk) throw new Error("Downloaded bundle is empty.");
|
|
1104
|
+
},
|
|
1105
|
+
{ attempts: 3, baseDelayMs: 500, maxDelayMs: 4e3 }
|
|
1106
|
+
);
|
|
1062
1107
|
await deleteFileIfExists(targetUri);
|
|
1063
1108
|
await FileSystem.moveAsync({ from: tmpUri, to: targetUri });
|
|
1064
1109
|
const finalOk = await getExistingNonEmptyFileUri(targetUri);
|
|
@@ -1071,28 +1116,44 @@ async function safeReplaceFileFromUrl(url, targetUri, tmpKey) {
|
|
|
1071
1116
|
async function pollBundle(appId, bundleId, opts) {
|
|
1072
1117
|
const start = Date.now();
|
|
1073
1118
|
while (true) {
|
|
1074
|
-
|
|
1075
|
-
|
|
1119
|
+
try {
|
|
1120
|
+
const bundle = await bundlesRepository.getById(appId, bundleId);
|
|
1121
|
+
if (bundle.status === "succeeded" || bundle.status === "failed") return bundle;
|
|
1122
|
+
} catch (e) {
|
|
1123
|
+
if (!isRetryableNetworkError(e)) {
|
|
1124
|
+
throw e;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1076
1127
|
if (Date.now() - start > opts.timeoutMs) {
|
|
1077
1128
|
throw new Error("Bundle build timed out.");
|
|
1078
1129
|
}
|
|
1079
|
-
await
|
|
1130
|
+
await sleep(opts.intervalMs);
|
|
1080
1131
|
}
|
|
1081
1132
|
}
|
|
1082
1133
|
async function resolveBundlePath(src, platform, mode) {
|
|
1083
1134
|
const { appId, commitId } = src;
|
|
1084
1135
|
const dir = bundlesCacheDir();
|
|
1085
1136
|
await ensureDir(dir);
|
|
1086
|
-
const initiate = await
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1137
|
+
const initiate = await withRetry(
|
|
1138
|
+
async () => {
|
|
1139
|
+
return await bundlesRepository.initiate(appId, {
|
|
1140
|
+
platform,
|
|
1141
|
+
commitId: commitId ?? void 0,
|
|
1142
|
+
idempotencyKey: `${appId}:${commitId ?? "head"}:${platform}`
|
|
1143
|
+
});
|
|
1144
|
+
},
|
|
1145
|
+
{ attempts: 3, baseDelayMs: 500, maxDelayMs: 4e3 }
|
|
1146
|
+
);
|
|
1091
1147
|
const finalBundle = initiate.status === "succeeded" || initiate.status === "failed" ? initiate : await pollBundle(appId, initiate.id, { timeoutMs: 3 * 60 * 1e3, intervalMs: 1200 });
|
|
1092
1148
|
if (finalBundle.status === "failed") {
|
|
1093
1149
|
throw new Error("Bundle build failed.");
|
|
1094
1150
|
}
|
|
1095
|
-
const signed = await
|
|
1151
|
+
const signed = await withRetry(
|
|
1152
|
+
async () => {
|
|
1153
|
+
return await bundlesRepository.getSignedDownloadUrl(appId, finalBundle.id, { redirect: false });
|
|
1154
|
+
},
|
|
1155
|
+
{ attempts: 3, baseDelayMs: 500, maxDelayMs: 4e3 }
|
|
1156
|
+
);
|
|
1096
1157
|
const bundlePath = mode === "base" ? await safeReplaceFileFromUrl(
|
|
1097
1158
|
signed.url,
|
|
1098
1159
|
toBundleFileUri(baseBundleKey(appId, platform)),
|
|
@@ -1108,6 +1169,7 @@ function useBundleManager({
|
|
|
1108
1169
|
const [bundlePath, setBundlePath] = React5.useState(null);
|
|
1109
1170
|
const [renderToken, setRenderToken] = React5.useState(0);
|
|
1110
1171
|
const [loading, setLoading] = React5.useState(false);
|
|
1172
|
+
const [loadingMode, setLoadingMode] = React5.useState(null);
|
|
1111
1173
|
const [statusLabel, setStatusLabel] = React5.useState(null);
|
|
1112
1174
|
const [error, setError] = React5.useState(null);
|
|
1113
1175
|
const [isTesting, setIsTesting] = React5.useState(false);
|
|
@@ -1123,6 +1185,7 @@ function useBundleManager({
|
|
|
1123
1185
|
baseOpIdRef.current += 1;
|
|
1124
1186
|
if (activeLoadModeRef.current === "base") {
|
|
1125
1187
|
setLoading(false);
|
|
1188
|
+
setLoadingMode(null);
|
|
1126
1189
|
setStatusLabel(null);
|
|
1127
1190
|
activeLoadModeRef.current = null;
|
|
1128
1191
|
}
|
|
@@ -1187,6 +1250,7 @@ function useBundleManager({
|
|
|
1187
1250
|
const opId = mode === "base" ? ++baseOpIdRef.current : ++testOpIdRef.current;
|
|
1188
1251
|
activeLoadModeRef.current = mode;
|
|
1189
1252
|
setLoading(true);
|
|
1253
|
+
setLoadingMode(mode);
|
|
1190
1254
|
setError(null);
|
|
1191
1255
|
setStatusLabel(mode === "test" ? "Loading test bundle\u2026" : "Loading latest build\u2026");
|
|
1192
1256
|
if (mode === "base") {
|
|
@@ -1229,6 +1293,7 @@ function useBundleManager({
|
|
|
1229
1293
|
if (mode === "base" && opId !== baseOpIdRef.current) return;
|
|
1230
1294
|
if (mode === "test" && opId !== testOpIdRef.current) return;
|
|
1231
1295
|
setLoading(false);
|
|
1296
|
+
setLoadingMode(null);
|
|
1232
1297
|
if (activeLoadModeRef.current === mode) activeLoadModeRef.current = null;
|
|
1233
1298
|
}
|
|
1234
1299
|
}, [activateCachedBase, platform]);
|
|
@@ -1250,7 +1315,7 @@ function useBundleManager({
|
|
|
1250
1315
|
if (!canRequestLatest) return;
|
|
1251
1316
|
void loadBase();
|
|
1252
1317
|
}, [base.appId, base.commitId, platform, canRequestLatest, loadBase]);
|
|
1253
|
-
return { bundlePath, renderToken, loading, statusLabel, error, isTesting, loadBase, loadTest, restoreBase };
|
|
1318
|
+
return { bundlePath, renderToken, loading, loadingMode, statusLabel, error, isTesting, loadBase, loadTest, restoreBase };
|
|
1254
1319
|
}
|
|
1255
1320
|
|
|
1256
1321
|
// src/studio/hooks/useMergeRequests.ts
|
|
@@ -1509,6 +1574,8 @@ function useMergeRequests(params) {
|
|
|
1509
1574
|
|
|
1510
1575
|
// src/studio/hooks/useAttachmentUpload.ts
|
|
1511
1576
|
var React7 = __toESM(require("react"));
|
|
1577
|
+
var import_react_native5 = require("react-native");
|
|
1578
|
+
var FileSystem2 = __toESM(require("expo-file-system/legacy"));
|
|
1512
1579
|
|
|
1513
1580
|
// src/data/attachment/remote.ts
|
|
1514
1581
|
var AttachmentRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -1548,6 +1615,40 @@ var attachmentRepository = new AttachmentRepositoryImpl(
|
|
|
1548
1615
|
);
|
|
1549
1616
|
|
|
1550
1617
|
// src/studio/hooks/useAttachmentUpload.ts
|
|
1618
|
+
async function dataUrlToBlobAndroid(dataUrl) {
|
|
1619
|
+
const normalized = dataUrl.startsWith("data:") ? dataUrl : `data:image/png;base64,${dataUrl}`;
|
|
1620
|
+
const comma = normalized.indexOf(",");
|
|
1621
|
+
if (comma === -1) {
|
|
1622
|
+
throw new Error("Invalid data URL (missing comma separator)");
|
|
1623
|
+
}
|
|
1624
|
+
const header = normalized.slice(0, comma);
|
|
1625
|
+
const base64 = normalized.slice(comma + 1);
|
|
1626
|
+
const mimeMatch = header.match(/data:(.*?);base64/i);
|
|
1627
|
+
const mimeType = (mimeMatch == null ? void 0 : mimeMatch[1]) ?? "application/octet-stream";
|
|
1628
|
+
const cacheDir = FileSystem2.cacheDirectory;
|
|
1629
|
+
if (!cacheDir) {
|
|
1630
|
+
throw new Error("expo-file-system cacheDirectory is unavailable");
|
|
1631
|
+
}
|
|
1632
|
+
const fileUri = `${cacheDir}attachment-${Date.now()}-${Math.random().toString(16).slice(2)}.bin`;
|
|
1633
|
+
await FileSystem2.writeAsStringAsync(fileUri, base64, {
|
|
1634
|
+
encoding: FileSystem2.EncodingType.Base64
|
|
1635
|
+
});
|
|
1636
|
+
try {
|
|
1637
|
+
const resp = await fetch(fileUri);
|
|
1638
|
+
const blob = await resp.blob();
|
|
1639
|
+
return blob.type ? blob : new Blob([blob], { type: mimeType });
|
|
1640
|
+
} finally {
|
|
1641
|
+
void FileSystem2.deleteAsync(fileUri, { idempotent: true }).catch(() => {
|
|
1642
|
+
});
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
function getMimeTypeFromDataUrl(dataUrl) {
|
|
1646
|
+
const normalized = dataUrl.startsWith("data:") ? dataUrl : `data:image/png;base64,${dataUrl}`;
|
|
1647
|
+
const comma = normalized.indexOf(",");
|
|
1648
|
+
const header = comma === -1 ? normalized : normalized.slice(0, comma);
|
|
1649
|
+
const mimeMatch = header.match(/data:(.*?);base64/i);
|
|
1650
|
+
return (mimeMatch == null ? void 0 : mimeMatch[1]) ?? "image/png";
|
|
1651
|
+
}
|
|
1551
1652
|
function useAttachmentUpload() {
|
|
1552
1653
|
const [uploading, setUploading] = React7.useState(false);
|
|
1553
1654
|
const [error, setError] = React7.useState(null);
|
|
@@ -1560,15 +1661,15 @@ function useAttachmentUpload() {
|
|
|
1560
1661
|
const blobs = await Promise.all(
|
|
1561
1662
|
dataUrls.map(async (dataUrl, idx) => {
|
|
1562
1663
|
const normalized = dataUrl.startsWith("data:") ? dataUrl : `data:image/png;base64,${dataUrl}`;
|
|
1563
|
-
const
|
|
1564
|
-
const
|
|
1565
|
-
return { blob, idx };
|
|
1664
|
+
const blob = import_react_native5.Platform.OS === "android" ? await dataUrlToBlobAndroid(normalized) : await (await fetch(normalized)).blob();
|
|
1665
|
+
const mimeType = getMimeTypeFromDataUrl(normalized);
|
|
1666
|
+
return { blob, idx, mimeType };
|
|
1566
1667
|
})
|
|
1567
1668
|
);
|
|
1568
|
-
const files = blobs.map(({ blob }, idx) => ({
|
|
1669
|
+
const files = blobs.map(({ blob, mimeType }, idx) => ({
|
|
1569
1670
|
name: `attachment-${Date.now()}-${idx}.png`,
|
|
1570
1671
|
size: blob.size,
|
|
1571
|
-
mimeType
|
|
1672
|
+
mimeType
|
|
1572
1673
|
}));
|
|
1573
1674
|
const presign = await attachmentRepository.presign({ threadId, appId, files });
|
|
1574
1675
|
await Promise.all(presign.uploads.map((u, index) => attachmentRepository.upload(u, blobs[index].blob)));
|
|
@@ -1692,14 +1793,14 @@ function hasNoOutcomeAfterLastHuman(messages) {
|
|
|
1692
1793
|
}
|
|
1693
1794
|
|
|
1694
1795
|
// src/studio/ui/RuntimeRenderer.tsx
|
|
1695
|
-
var
|
|
1796
|
+
var import_react_native6 = require("react-native");
|
|
1696
1797
|
var import_runtime = require("@comergehq/runtime");
|
|
1697
1798
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1698
|
-
function RuntimeRenderer({ appKey, bundlePath, renderToken, style }) {
|
|
1699
|
-
if (!bundlePath) {
|
|
1700
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1799
|
+
function RuntimeRenderer({ appKey, bundlePath, forcePreparing, renderToken, style }) {
|
|
1800
|
+
if (!bundlePath || forcePreparing) {
|
|
1801
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, { style: [{ flex: 1, justifyContent: "center", alignItems: "center", padding: 24 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { variant: "bodyMuted", children: "Preparing app\u2026" }) });
|
|
1701
1802
|
}
|
|
1702
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1803
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native6.View, { style: [{ flex: 1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1703
1804
|
import_runtime.ComergeRuntimeRenderer,
|
|
1704
1805
|
{
|
|
1705
1806
|
appKey,
|
|
@@ -1711,17 +1812,17 @@ function RuntimeRenderer({ appKey, bundlePath, renderToken, style }) {
|
|
|
1711
1812
|
}
|
|
1712
1813
|
|
|
1713
1814
|
// src/studio/ui/StudioOverlay.tsx
|
|
1714
|
-
var
|
|
1715
|
-
var
|
|
1815
|
+
var React39 = __toESM(require("react"));
|
|
1816
|
+
var import_react_native53 = require("react-native");
|
|
1716
1817
|
|
|
1717
1818
|
// src/components/studio-sheet/StudioBottomSheet.tsx
|
|
1718
1819
|
var React9 = __toESM(require("react"));
|
|
1719
|
-
var
|
|
1820
|
+
var import_react_native8 = require("react-native");
|
|
1720
1821
|
var import_bottom_sheet = __toESM(require("@gorhom/bottom-sheet"));
|
|
1721
1822
|
var import_react_native_safe_area_context = require("react-native-safe-area-context");
|
|
1722
1823
|
|
|
1723
1824
|
// src/components/studio-sheet/StudioSheetBackground.tsx
|
|
1724
|
-
var
|
|
1825
|
+
var import_react_native7 = require("react-native");
|
|
1725
1826
|
var import_liquid_glass = require("@callstack/liquid-glass");
|
|
1726
1827
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1727
1828
|
function StudioSheetBackground({
|
|
@@ -1729,7 +1830,7 @@ function StudioSheetBackground({
|
|
|
1729
1830
|
renderBackground
|
|
1730
1831
|
}) {
|
|
1731
1832
|
const theme = useTheme();
|
|
1732
|
-
const radius =
|
|
1833
|
+
const radius = import_react_native7.Platform.OS === "ios" ? 39 : 16;
|
|
1733
1834
|
const fallbackBgColor = theme.scheme === "dark" ? "rgba(11, 8, 15, 0.85)" : "rgba(255, 255, 255, 0.85)";
|
|
1734
1835
|
const secondaryBgBaseColor = theme.scheme === "dark" ? "rgb(24, 24, 27)" : "rgb(173, 173, 173)";
|
|
1735
1836
|
const containerStyle = {
|
|
@@ -1750,7 +1851,7 @@ function StudioSheetBackground({
|
|
|
1750
1851
|
}
|
|
1751
1852
|
),
|
|
1752
1853
|
import_liquid_glass.isLiquidGlassSupported && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1753
|
-
|
|
1854
|
+
import_react_native7.View,
|
|
1754
1855
|
{
|
|
1755
1856
|
style: [
|
|
1756
1857
|
containerStyle,
|
|
@@ -1775,7 +1876,7 @@ var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
|
1775
1876
|
function StudioBottomSheet({
|
|
1776
1877
|
open,
|
|
1777
1878
|
onOpenChange,
|
|
1778
|
-
snapPoints = ["
|
|
1879
|
+
snapPoints = ["100%"],
|
|
1779
1880
|
sheetRef,
|
|
1780
1881
|
background,
|
|
1781
1882
|
children,
|
|
@@ -1786,13 +1887,13 @@ function StudioBottomSheet({
|
|
|
1786
1887
|
const internalSheetRef = React9.useRef(null);
|
|
1787
1888
|
const resolvedSheetRef = sheetRef ?? internalSheetRef;
|
|
1788
1889
|
const currentIndexRef = React9.useRef(open ? snapPoints.length - 1 : -1);
|
|
1789
|
-
const lastAppStateRef = React9.useRef(
|
|
1890
|
+
const lastAppStateRef = React9.useRef(import_react_native8.AppState.currentState);
|
|
1790
1891
|
React9.useEffect(() => {
|
|
1791
|
-
const sub =
|
|
1892
|
+
const sub = import_react_native8.AppState.addEventListener("change", (state) => {
|
|
1792
1893
|
const prev = lastAppStateRef.current;
|
|
1793
1894
|
lastAppStateRef.current = state;
|
|
1794
1895
|
if (state === "background" || state === "inactive") {
|
|
1795
|
-
|
|
1896
|
+
import_react_native8.Keyboard.dismiss();
|
|
1796
1897
|
return;
|
|
1797
1898
|
}
|
|
1798
1899
|
if (state !== "active") return;
|
|
@@ -1800,7 +1901,7 @@ function StudioBottomSheet({
|
|
|
1800
1901
|
if (!sheet) return;
|
|
1801
1902
|
const idx = currentIndexRef.current;
|
|
1802
1903
|
if (open && idx >= 0) {
|
|
1803
|
-
|
|
1904
|
+
import_react_native8.Keyboard.dismiss();
|
|
1804
1905
|
requestAnimationFrame(() => sheet.snapToIndex(idx));
|
|
1805
1906
|
setTimeout(() => sheet.snapToIndex(idx), 120);
|
|
1806
1907
|
}
|
|
@@ -1829,9 +1930,9 @@ function StudioBottomSheet({
|
|
|
1829
1930
|
ref: resolvedSheetRef,
|
|
1830
1931
|
index: open ? snapPoints.length - 1 : -1,
|
|
1831
1932
|
snapPoints,
|
|
1933
|
+
enableDynamicSizing: false,
|
|
1832
1934
|
enablePanDownToClose: true,
|
|
1833
|
-
|
|
1834
|
-
keyboardBlurBehavior: "restore",
|
|
1935
|
+
enableContentPanningGesture: false,
|
|
1835
1936
|
android_keyboardInputMode: "adjustResize",
|
|
1836
1937
|
backgroundComponent: (props) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StudioSheetBackground, { ...props, renderBackground: background == null ? void 0 : background.renderBackground }),
|
|
1837
1938
|
topInset: insets.top,
|
|
@@ -1839,19 +1940,19 @@ function StudioBottomSheet({
|
|
|
1839
1940
|
handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
|
|
1840
1941
|
onChange: handleChange,
|
|
1841
1942
|
...bottomSheetProps,
|
|
1842
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1943
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native8.View, { style: { flex: 1, overflow: "hidden" }, children })
|
|
1843
1944
|
}
|
|
1844
1945
|
);
|
|
1845
1946
|
}
|
|
1846
1947
|
|
|
1847
1948
|
// src/components/studio-sheet/StudioSheetPager.tsx
|
|
1848
1949
|
var React10 = __toESM(require("react"));
|
|
1849
|
-
var
|
|
1950
|
+
var import_react_native9 = require("react-native");
|
|
1850
1951
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1851
1952
|
function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
1852
|
-
const anim = React10.useRef(new
|
|
1953
|
+
const anim = React10.useRef(new import_react_native9.Animated.Value(activePage === "chat" ? 1 : 0)).current;
|
|
1853
1954
|
React10.useEffect(() => {
|
|
1854
|
-
|
|
1955
|
+
import_react_native9.Animated.spring(anim, {
|
|
1855
1956
|
toValue: activePage === "chat" ? 1 : 0,
|
|
1856
1957
|
useNativeDriver: true,
|
|
1857
1958
|
tension: 65,
|
|
@@ -1860,9 +1961,9 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1860
1961
|
}, [activePage, anim]);
|
|
1861
1962
|
const previewTranslateX = anim.interpolate({ inputRange: [0, 1], outputRange: [0, -width] });
|
|
1862
1963
|
const chatTranslateX = anim.interpolate({ inputRange: [0, 1], outputRange: [width, 0] });
|
|
1863
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1964
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native9.Animated.View, { style: [{ flex: 1 }, style], children: [
|
|
1864
1965
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1865
|
-
|
|
1966
|
+
import_react_native9.Animated.View,
|
|
1866
1967
|
{
|
|
1867
1968
|
style: [
|
|
1868
1969
|
{
|
|
@@ -1879,7 +1980,7 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1879
1980
|
}
|
|
1880
1981
|
),
|
|
1881
1982
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1882
|
-
|
|
1983
|
+
import_react_native9.Animated.View,
|
|
1883
1984
|
{
|
|
1884
1985
|
style: [
|
|
1885
1986
|
{
|
|
@@ -1900,7 +2001,7 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1900
2001
|
|
|
1901
2002
|
// src/components/floating-draggable-button/FloatingDraggableButton.tsx
|
|
1902
2003
|
var import_react = require("react");
|
|
1903
|
-
var
|
|
2004
|
+
var import_react_native10 = require("react-native");
|
|
1904
2005
|
var Haptics = __toESM(require("expo-haptics"));
|
|
1905
2006
|
var import_react_native_reanimated = __toESM(require("react-native-reanimated"));
|
|
1906
2007
|
var import_liquid_glass2 = require("@callstack/liquid-glass");
|
|
@@ -1959,7 +2060,7 @@ function FloatingDraggableButton({
|
|
|
1959
2060
|
backgroundColor
|
|
1960
2061
|
}) {
|
|
1961
2062
|
const theme = useTheme();
|
|
1962
|
-
const { width, height } = (0,
|
|
2063
|
+
const { width, height } = (0, import_react_native10.useWindowDimensions)();
|
|
1963
2064
|
const isDanger = variant === "danger";
|
|
1964
2065
|
const onPressRef = (0, import_react.useRef)(onPress);
|
|
1965
2066
|
(0, import_react.useEffect)(() => {
|
|
@@ -2062,7 +2163,7 @@ function FloatingDraggableButton({
|
|
|
2062
2163
|
}
|
|
2063
2164
|
}, [forceShowTrigger, visible, animateIn]);
|
|
2064
2165
|
const panResponder = (0, import_react.useRef)(
|
|
2065
|
-
|
|
2166
|
+
import_react_native10.PanResponder.create({
|
|
2066
2167
|
onStartShouldSetPanResponder: () => true,
|
|
2067
2168
|
onMoveShouldSetPanResponder: () => true,
|
|
2068
2169
|
onPanResponderGrant: () => {
|
|
@@ -2125,24 +2226,24 @@ function FloatingDraggableButton({
|
|
|
2125
2226
|
interactive: true,
|
|
2126
2227
|
effect: "clear",
|
|
2127
2228
|
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2128
|
-
|
|
2229
|
+
import_react_native10.Pressable,
|
|
2129
2230
|
{
|
|
2130
2231
|
onPress: () => {
|
|
2131
2232
|
if (!disabled) animateOut();
|
|
2132
2233
|
},
|
|
2133
2234
|
style: styles.buttonInner,
|
|
2134
2235
|
android_ripple: { color: "rgba(255, 255, 255, 0.3)", borderless: true },
|
|
2135
|
-
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2236
|
+
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native10.View, {})
|
|
2136
2237
|
}
|
|
2137
2238
|
)
|
|
2138
2239
|
}
|
|
2139
2240
|
) }),
|
|
2140
|
-
badgeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2241
|
+
badgeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native10.View, { style: [styles.badge, { backgroundColor: theme.colors.danger }], children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native10.Text, { style: [styles.badgeText, { color: theme.colors.onDanger }], children: badgeCount > 99 ? "99+" : badgeCount }) })
|
|
2141
2242
|
]
|
|
2142
2243
|
}
|
|
2143
2244
|
);
|
|
2144
2245
|
}
|
|
2145
|
-
var styles =
|
|
2246
|
+
var styles = import_react_native10.StyleSheet.create({
|
|
2146
2247
|
floatingButton: {
|
|
2147
2248
|
position: "absolute",
|
|
2148
2249
|
justifyContent: "center",
|
|
@@ -2179,7 +2280,7 @@ var styles = import_react_native9.StyleSheet.create({
|
|
|
2179
2280
|
|
|
2180
2281
|
// src/components/overlays/EdgeGlowFrame.tsx
|
|
2181
2282
|
var React11 = __toESM(require("react"));
|
|
2182
|
-
var
|
|
2283
|
+
var import_react_native11 = require("react-native");
|
|
2183
2284
|
var import_expo_linear_gradient = require("expo-linear-gradient");
|
|
2184
2285
|
|
|
2185
2286
|
// src/components/utils/color.ts
|
|
@@ -2221,9 +2322,9 @@ function EdgeGlowFrame({
|
|
|
2221
2322
|
}) {
|
|
2222
2323
|
const theme = useTheme();
|
|
2223
2324
|
const alpha = Math.max(0, Math.min(1, intensity));
|
|
2224
|
-
const anim = React11.useRef(new
|
|
2325
|
+
const anim = React11.useRef(new import_react_native11.Animated.Value(visible ? 1 : 0)).current;
|
|
2225
2326
|
React11.useEffect(() => {
|
|
2226
|
-
|
|
2327
|
+
import_react_native11.Animated.timing(anim, {
|
|
2227
2328
|
toValue: visible ? 1 : 0,
|
|
2228
2329
|
duration: 300,
|
|
2229
2330
|
useNativeDriver: true
|
|
@@ -2232,8 +2333,8 @@ function EdgeGlowFrame({
|
|
|
2232
2333
|
const c = baseColor(role, theme);
|
|
2233
2334
|
const strong = withAlpha(c, 0.6 * alpha);
|
|
2234
2335
|
const soft = withAlpha(c, 0.22 * alpha);
|
|
2235
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2236
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2336
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native11.Animated.View, { pointerEvents: "none", style: [{ position: "absolute", inset: 0, opacity: anim }, style], children: [
|
|
2337
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native11.View, { style: { position: "absolute", top: 0, left: 0, right: 0, height: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2237
2338
|
import_expo_linear_gradient.LinearGradient,
|
|
2238
2339
|
{
|
|
2239
2340
|
colors: [strong, soft, "transparent"],
|
|
@@ -2242,7 +2343,7 @@ function EdgeGlowFrame({
|
|
|
2242
2343
|
style: { width: "100%", height: "100%" }
|
|
2243
2344
|
}
|
|
2244
2345
|
) }),
|
|
2245
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2346
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native11.View, { style: { position: "absolute", bottom: 0, left: 0, right: 0, height: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2246
2347
|
import_expo_linear_gradient.LinearGradient,
|
|
2247
2348
|
{
|
|
2248
2349
|
colors: ["transparent", soft, strong],
|
|
@@ -2251,7 +2352,7 @@ function EdgeGlowFrame({
|
|
|
2251
2352
|
style: { width: "100%", height: "100%" }
|
|
2252
2353
|
}
|
|
2253
2354
|
) }),
|
|
2254
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2355
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native11.View, { style: { position: "absolute", top: 0, bottom: 0, left: 0, width: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2255
2356
|
import_expo_linear_gradient.LinearGradient,
|
|
2256
2357
|
{
|
|
2257
2358
|
colors: [strong, soft, "transparent"],
|
|
@@ -2260,7 +2361,7 @@ function EdgeGlowFrame({
|
|
|
2260
2361
|
style: { width: "100%", height: "100%" }
|
|
2261
2362
|
}
|
|
2262
2363
|
) }),
|
|
2263
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2364
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native11.View, { style: { position: "absolute", top: 0, bottom: 0, right: 0, width: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2264
2365
|
import_expo_linear_gradient.LinearGradient,
|
|
2265
2366
|
{
|
|
2266
2367
|
colors: ["transparent", soft, strong],
|
|
@@ -2274,12 +2375,12 @@ function EdgeGlowFrame({
|
|
|
2274
2375
|
|
|
2275
2376
|
// src/components/draw/DrawModeOverlay.tsx
|
|
2276
2377
|
var React14 = __toESM(require("react"));
|
|
2277
|
-
var
|
|
2378
|
+
var import_react_native15 = require("react-native");
|
|
2278
2379
|
var import_react_native_view_shot = require("react-native-view-shot");
|
|
2279
2380
|
|
|
2280
2381
|
// src/components/draw/DrawSurface.tsx
|
|
2281
2382
|
var React12 = __toESM(require("react"));
|
|
2282
|
-
var
|
|
2383
|
+
var import_react_native12 = require("react-native");
|
|
2283
2384
|
var import_react_native_svg = __toESM(require("react-native-svg"));
|
|
2284
2385
|
|
|
2285
2386
|
// src/components/draw/strokes.ts
|
|
@@ -2350,7 +2451,7 @@ function DrawSurface({
|
|
|
2350
2451
|
triggerRender();
|
|
2351
2452
|
}, [color, onAddStroke, strokeWidth, triggerRender]);
|
|
2352
2453
|
const panResponder = React12.useMemo(
|
|
2353
|
-
() =>
|
|
2454
|
+
() => import_react_native12.PanResponder.create({
|
|
2354
2455
|
onStartShouldSetPanResponder: () => true,
|
|
2355
2456
|
onMoveShouldSetPanResponder: () => true,
|
|
2356
2457
|
onPanResponderGrant: onStart,
|
|
@@ -2362,7 +2463,7 @@ function DrawSurface({
|
|
|
2362
2463
|
);
|
|
2363
2464
|
const currentPath = pointsToSmoothPath(currentPointsRef.current);
|
|
2364
2465
|
void renderTick;
|
|
2365
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2466
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native12.View, { style: [import_react_native12.StyleSheet.absoluteFill, styles2.container, style], ...panResponder.panHandlers, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native_svg.default, { style: import_react_native12.StyleSheet.absoluteFill, width: "100%", height: "100%", children: [
|
|
2366
2467
|
strokes.map((s, idx) => {
|
|
2367
2468
|
const d = pointsToSmoothPath(s.points);
|
|
2368
2469
|
if (!d) return null;
|
|
@@ -2392,7 +2493,7 @@ function DrawSurface({
|
|
|
2392
2493
|
) : null
|
|
2393
2494
|
] }) });
|
|
2394
2495
|
}
|
|
2395
|
-
var styles2 =
|
|
2496
|
+
var styles2 = import_react_native12.StyleSheet.create({
|
|
2396
2497
|
container: {
|
|
2397
2498
|
zIndex: 5
|
|
2398
2499
|
}
|
|
@@ -2400,7 +2501,7 @@ var styles2 = import_react_native11.StyleSheet.create({
|
|
|
2400
2501
|
|
|
2401
2502
|
// src/components/draw/DrawToolbar.tsx
|
|
2402
2503
|
var React13 = __toESM(require("react"));
|
|
2403
|
-
var
|
|
2504
|
+
var import_react_native14 = require("react-native");
|
|
2404
2505
|
var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
|
|
2405
2506
|
var import_lucide_react_native = require("lucide-react-native");
|
|
2406
2507
|
|
|
@@ -2419,7 +2520,7 @@ async function impact(style) {
|
|
|
2419
2520
|
}
|
|
2420
2521
|
|
|
2421
2522
|
// src/components/draw/DrawColorPicker.tsx
|
|
2422
|
-
var
|
|
2523
|
+
var import_react_native13 = require("react-native");
|
|
2423
2524
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2424
2525
|
function DrawColorPicker({
|
|
2425
2526
|
colors,
|
|
@@ -2454,10 +2555,10 @@ function DrawColorPicker({
|
|
|
2454
2555
|
return { ...base, ...selectedStyle, ...whiteStyle };
|
|
2455
2556
|
};
|
|
2456
2557
|
if (!expanded) {
|
|
2457
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2558
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native13.Pressable, { onPress: onToggle, style: [swatchStyle(selected, true), style] });
|
|
2458
2559
|
}
|
|
2459
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2460
|
-
|
|
2560
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native13.View, { style: [{ flexDirection: "row", alignItems: "center", gap: 8 }, style], children: colors.map((c, idx) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2561
|
+
import_react_native13.Pressable,
|
|
2461
2562
|
{
|
|
2462
2563
|
onPress: () => {
|
|
2463
2564
|
onSelect(c);
|
|
@@ -2488,14 +2589,14 @@ function DrawToolbar({
|
|
|
2488
2589
|
style
|
|
2489
2590
|
}) {
|
|
2490
2591
|
const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
|
|
2491
|
-
const { width: screenWidth, height: screenHeight } = (0,
|
|
2592
|
+
const { width: screenWidth, height: screenHeight } = (0, import_react_native14.useWindowDimensions)();
|
|
2492
2593
|
const [expanded, setExpanded] = React13.useState(false);
|
|
2493
|
-
const pos = React13.useRef(new
|
|
2594
|
+
const pos = React13.useRef(new import_react_native14.Animated.ValueXY({ x: screenWidth / 2 - 110, y: -140 })).current;
|
|
2494
2595
|
const start = React13.useRef({ x: 0, y: 0 });
|
|
2495
2596
|
const currentPos = React13.useRef({ x: 0, y: 0 });
|
|
2496
2597
|
React13.useEffect(() => {
|
|
2497
2598
|
if (hidden) return;
|
|
2498
|
-
|
|
2599
|
+
import_react_native14.Animated.spring(pos.y, {
|
|
2499
2600
|
toValue: insets.top + 60,
|
|
2500
2601
|
useNativeDriver: true,
|
|
2501
2602
|
damping: 12,
|
|
@@ -2522,7 +2623,7 @@ function DrawToolbar({
|
|
|
2522
2623
|
[insets.top, screenHeight, screenWidth]
|
|
2523
2624
|
);
|
|
2524
2625
|
const panResponder = React13.useMemo(
|
|
2525
|
-
() =>
|
|
2626
|
+
() => import_react_native14.PanResponder.create({
|
|
2526
2627
|
onStartShouldSetPanResponder: () => false,
|
|
2527
2628
|
onMoveShouldSetPanResponder: (_e, g) => Math.abs(g.dx) > 5 || Math.abs(g.dy) > 5,
|
|
2528
2629
|
onPanResponderGrant: () => {
|
|
@@ -2534,7 +2635,7 @@ function DrawToolbar({
|
|
|
2534
2635
|
},
|
|
2535
2636
|
onPanResponderRelease: () => {
|
|
2536
2637
|
const next = clamp2(currentPos.current.x, currentPos.current.y);
|
|
2537
|
-
|
|
2638
|
+
import_react_native14.Animated.spring(pos, { toValue: next, useNativeDriver: true }).start();
|
|
2538
2639
|
}
|
|
2539
2640
|
}),
|
|
2540
2641
|
[clamp2, pos]
|
|
@@ -2551,7 +2652,7 @@ function DrawToolbar({
|
|
|
2551
2652
|
const isDisabled = Boolean(disabled) || Boolean(capturingDisabled);
|
|
2552
2653
|
const [pressed, setPressed] = React13.useState(false);
|
|
2553
2654
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2554
|
-
|
|
2655
|
+
import_react_native14.View,
|
|
2555
2656
|
{
|
|
2556
2657
|
style: {
|
|
2557
2658
|
width: 28,
|
|
@@ -2563,7 +2664,7 @@ function DrawToolbar({
|
|
|
2563
2664
|
opacity: isDisabled ? 0.5 : pressed ? 0.85 : 1
|
|
2564
2665
|
},
|
|
2565
2666
|
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2566
|
-
|
|
2667
|
+
import_react_native14.Pressable,
|
|
2567
2668
|
{
|
|
2568
2669
|
accessibilityRole: "button",
|
|
2569
2670
|
accessibilityLabel,
|
|
@@ -2580,7 +2681,7 @@ function DrawToolbar({
|
|
|
2580
2681
|
);
|
|
2581
2682
|
}
|
|
2582
2683
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2583
|
-
|
|
2684
|
+
import_react_native14.Animated.View,
|
|
2584
2685
|
{
|
|
2585
2686
|
style: [
|
|
2586
2687
|
{
|
|
@@ -2597,7 +2698,7 @@ function DrawToolbar({
|
|
|
2597
2698
|
],
|
|
2598
2699
|
...panResponder.panHandlers,
|
|
2599
2700
|
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2600
|
-
|
|
2701
|
+
import_react_native14.View,
|
|
2601
2702
|
{
|
|
2602
2703
|
style: {
|
|
2603
2704
|
backgroundColor: "#F43F5E",
|
|
@@ -2605,7 +2706,7 @@ function DrawToolbar({
|
|
|
2605
2706
|
padding: 12,
|
|
2606
2707
|
minWidth: 220
|
|
2607
2708
|
},
|
|
2608
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2709
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native14.View, { style: { flexDirection: "row", alignItems: "center", gap: 8 }, children: [
|
|
2609
2710
|
renderDragHandle ? renderDragHandle() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react_native.GripVertical, { size: 20, color: "rgba(255, 255, 255, 0.6)" }),
|
|
2610
2711
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2611
2712
|
DrawColorPicker,
|
|
@@ -2623,7 +2724,7 @@ function DrawToolbar({
|
|
|
2623
2724
|
}
|
|
2624
2725
|
}
|
|
2625
2726
|
),
|
|
2626
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2727
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native14.View, { style: { width: 1, height: 20, backgroundColor: "rgba(255, 255, 255, 0.3)", marginHorizontal: 4 } }),
|
|
2627
2728
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2628
2729
|
CircleActionButton,
|
|
2629
2730
|
{
|
|
@@ -2661,7 +2762,7 @@ function DrawToolbar({
|
|
|
2661
2762
|
void impact("medium");
|
|
2662
2763
|
onDone();
|
|
2663
2764
|
},
|
|
2664
|
-
children: capturing ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2765
|
+
children: capturing ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native14.ActivityIndicator, { color: "#FFFFFF", size: "small" }) : renderDoneIcon ? renderDoneIcon() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react_native.Check, { size: 16, color: "#FFFFFF" })
|
|
2665
2766
|
}
|
|
2666
2767
|
)
|
|
2667
2768
|
] })
|
|
@@ -2746,7 +2847,7 @@ function DrawModeOverlay({
|
|
|
2746
2847
|
}
|
|
2747
2848
|
}, [captureTargetRef, capturing, onCapture]);
|
|
2748
2849
|
if (!visible) return null;
|
|
2749
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2850
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native15.View, { style: [import_react_native15.StyleSheet.absoluteFill, styles3.root, style], pointerEvents: "box-none", children: [
|
|
2750
2851
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(EdgeGlowFrame, { visible: !hideUi, role: "danger", thickness: 50, intensity: 1 }),
|
|
2751
2852
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2752
2853
|
DrawSurface,
|
|
@@ -2777,7 +2878,7 @@ function DrawModeOverlay({
|
|
|
2777
2878
|
)
|
|
2778
2879
|
] });
|
|
2779
2880
|
}
|
|
2780
|
-
var styles3 =
|
|
2881
|
+
var styles3 = import_react_native15.StyleSheet.create({
|
|
2781
2882
|
root: {
|
|
2782
2883
|
zIndex: 9999
|
|
2783
2884
|
}
|
|
@@ -2785,7 +2886,7 @@ var styles3 = import_react_native14.StyleSheet.create({
|
|
|
2785
2886
|
|
|
2786
2887
|
// src/components/comments/AppCommentsSheet.tsx
|
|
2787
2888
|
var React21 = __toESM(require("react"));
|
|
2788
|
-
var
|
|
2889
|
+
var import_react_native21 = require("react-native");
|
|
2789
2890
|
var import_bottom_sheet3 = require("@gorhom/bottom-sheet");
|
|
2790
2891
|
var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
|
|
2791
2892
|
var import_liquid_glass4 = require("@callstack/liquid-glass");
|
|
@@ -2793,13 +2894,13 @@ var import_lucide_react_native4 = require("lucide-react-native");
|
|
|
2793
2894
|
|
|
2794
2895
|
// src/components/chat/ChatComposer.tsx
|
|
2795
2896
|
var React16 = __toESM(require("react"));
|
|
2796
|
-
var
|
|
2897
|
+
var import_react_native17 = require("react-native");
|
|
2797
2898
|
var import_liquid_glass3 = require("@callstack/liquid-glass");
|
|
2798
2899
|
var import_lucide_react_native3 = require("lucide-react-native");
|
|
2799
2900
|
|
|
2800
2901
|
// src/components/chat/MultilineTextInput.tsx
|
|
2801
2902
|
var React15 = __toESM(require("react"));
|
|
2802
|
-
var
|
|
2903
|
+
var import_react_native16 = require("react-native");
|
|
2803
2904
|
var import_bottom_sheet2 = require("@gorhom/bottom-sheet");
|
|
2804
2905
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2805
2906
|
var MultilineTextInput = React15.forwardRef(function MultilineTextInput2({ useBottomSheetTextInput = false, placeholder, placeholderTextColor, style, ...props }, ref) {
|
|
@@ -2822,7 +2923,7 @@ var MultilineTextInput = React15.forwardRef(function MultilineTextInput2({ useBo
|
|
|
2822
2923
|
style: [baseStyle, style],
|
|
2823
2924
|
textAlignVertical: "top"
|
|
2824
2925
|
};
|
|
2825
|
-
return useBottomSheetTextInput ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_bottom_sheet2.BottomSheetTextInput, { ref, ...commonProps }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2926
|
+
return useBottomSheetTextInput ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_bottom_sheet2.BottomSheetTextInput, { ref, ...commonProps }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native16.TextInput, { ref, ...commonProps });
|
|
2826
2927
|
});
|
|
2827
2928
|
|
|
2828
2929
|
// src/components/icons/StudioIcons.tsx
|
|
@@ -2875,9 +2976,9 @@ function AspectRatioThumbnail({
|
|
|
2875
2976
|
renderRemoveIcon
|
|
2876
2977
|
}) {
|
|
2877
2978
|
const [aspectRatio, setAspectRatio] = React16.useState(1);
|
|
2878
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2879
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2880
|
-
|
|
2979
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native17.View, { style: { height: THUMBNAIL_HEIGHT, aspectRatio, position: "relative" }, children: [
|
|
2980
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native17.View, { style: { flex: 1, borderRadius: 8, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2981
|
+
import_react_native17.Image,
|
|
2881
2982
|
{
|
|
2882
2983
|
source: { uri },
|
|
2883
2984
|
style: { width: "100%", height: "100%" },
|
|
@@ -2890,7 +2991,7 @@ function AspectRatioThumbnail({
|
|
|
2890
2991
|
}
|
|
2891
2992
|
) }),
|
|
2892
2993
|
onRemove ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2893
|
-
|
|
2994
|
+
import_react_native17.Pressable,
|
|
2894
2995
|
{
|
|
2895
2996
|
style: {
|
|
2896
2997
|
position: "absolute",
|
|
@@ -2938,8 +3039,8 @@ function ChatComposer({
|
|
|
2938
3039
|
const hasText = text.trim().length > 0;
|
|
2939
3040
|
const composerMinHeight = hasAttachments ? THUMBNAIL_HEIGHT + 44 + 24 : 44;
|
|
2940
3041
|
const isButtonDisabled = sending || disabled || sendDisabled;
|
|
2941
|
-
const maxInputHeight = React16.useMemo(() =>
|
|
2942
|
-
const shakeAnim = React16.useRef(new
|
|
3042
|
+
const maxInputHeight = React16.useMemo(() => import_react_native17.Dimensions.get("window").height * 0.5, []);
|
|
3043
|
+
const shakeAnim = React16.useRef(new import_react_native17.Animated.Value(0)).current;
|
|
2943
3044
|
const [sendPressed, setSendPressed] = React16.useState(false);
|
|
2944
3045
|
const inputRef = React16.useRef(null);
|
|
2945
3046
|
const prevAutoFocusRef = React16.useRef(false);
|
|
@@ -2955,12 +3056,12 @@ function ChatComposer({
|
|
|
2955
3056
|
}, [autoFocus, disabled, sending]);
|
|
2956
3057
|
const triggerShake = React16.useCallback(() => {
|
|
2957
3058
|
shakeAnim.setValue(0);
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
3059
|
+
import_react_native17.Animated.sequence([
|
|
3060
|
+
import_react_native17.Animated.timing(shakeAnim, { toValue: 10, duration: 50, useNativeDriver: true }),
|
|
3061
|
+
import_react_native17.Animated.timing(shakeAnim, { toValue: -10, duration: 50, useNativeDriver: true }),
|
|
3062
|
+
import_react_native17.Animated.timing(shakeAnim, { toValue: 10, duration: 50, useNativeDriver: true }),
|
|
3063
|
+
import_react_native17.Animated.timing(shakeAnim, { toValue: -10, duration: 50, useNativeDriver: true }),
|
|
3064
|
+
import_react_native17.Animated.timing(shakeAnim, { toValue: 0, duration: 50, useNativeDriver: true })
|
|
2964
3065
|
]).start();
|
|
2965
3066
|
}, [shakeAnim]);
|
|
2966
3067
|
const handleSend = React16.useCallback(async () => {
|
|
@@ -2976,12 +3077,12 @@ function ChatComposer({
|
|
|
2976
3077
|
const textareaBgColor = theme.scheme === "dark" ? "#18181B" : "#F6F6F6";
|
|
2977
3078
|
const placeholderTextColor = theme.scheme === "dark" ? "#A1A1AA" : "#71717A";
|
|
2978
3079
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2979
|
-
|
|
3080
|
+
import_react_native17.View,
|
|
2980
3081
|
{
|
|
2981
3082
|
style: [{ paddingHorizontal: 16, paddingBottom: 12, paddingTop: 8 }, style],
|
|
2982
3083
|
onLayout: (e) => onLayout == null ? void 0 : onLayout({ height: e.nativeEvent.layout.height }),
|
|
2983
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2984
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3084
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native17.View, { style: { flexDirection: "row", alignItems: "flex-end", gap: 8 }, children: [
|
|
3085
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native17.Animated.View, { style: { flex: 1, transform: [{ translateX: shakeAnim }] }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2985
3086
|
import_liquid_glass3.LiquidGlassView,
|
|
2986
3087
|
{
|
|
2987
3088
|
style: [
|
|
@@ -2994,7 +3095,7 @@ function ChatComposer({
|
|
|
2994
3095
|
effect: "clear",
|
|
2995
3096
|
children: [
|
|
2996
3097
|
hasAttachments ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2997
|
-
|
|
3098
|
+
import_react_native17.ScrollView,
|
|
2998
3099
|
{
|
|
2999
3100
|
horizontal: true,
|
|
3000
3101
|
showsHorizontalScrollIndicator: false,
|
|
@@ -3011,7 +3112,7 @@ function ChatComposer({
|
|
|
3011
3112
|
`attachment-${index}`
|
|
3012
3113
|
)),
|
|
3013
3114
|
onAddAttachment ? renderAddAttachment ? renderAddAttachment() : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3014
|
-
|
|
3115
|
+
import_react_native17.Pressable,
|
|
3015
3116
|
{
|
|
3016
3117
|
style: {
|
|
3017
3118
|
height: THUMBNAIL_HEIGHT,
|
|
@@ -3063,7 +3164,7 @@ function ChatComposer({
|
|
|
3063
3164
|
interactive: true,
|
|
3064
3165
|
effect: "clear",
|
|
3065
3166
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3066
|
-
|
|
3167
|
+
import_react_native17.View,
|
|
3067
3168
|
{
|
|
3068
3169
|
style: {
|
|
3069
3170
|
width: 44,
|
|
@@ -3074,7 +3175,7 @@ function ChatComposer({
|
|
|
3074
3175
|
opacity: isButtonDisabled ? 0.6 : sendPressed ? 0.9 : 1
|
|
3075
3176
|
},
|
|
3076
3177
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3077
|
-
|
|
3178
|
+
import_react_native17.Pressable,
|
|
3078
3179
|
{
|
|
3079
3180
|
accessibilityRole: "button",
|
|
3080
3181
|
accessibilityLabel: "Send",
|
|
@@ -3083,7 +3184,7 @@ function ChatComposer({
|
|
|
3083
3184
|
onPressIn: () => setSendPressed(true),
|
|
3084
3185
|
onPressOut: () => setSendPressed(false),
|
|
3085
3186
|
style: { flex: 1, alignItems: "center", justifyContent: "center" },
|
|
3086
|
-
children: sending ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3187
|
+
children: sending ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native17.ActivityIndicator, {}) : renderSendIcon ? renderSendIcon() : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconChevronRight, { size: 20, colorToken: "onPrimary" })
|
|
3087
3188
|
}
|
|
3088
3189
|
)
|
|
3089
3190
|
}
|
|
@@ -3097,10 +3198,10 @@ function ChatComposer({
|
|
|
3097
3198
|
|
|
3098
3199
|
// src/components/comments/CommentRow.tsx
|
|
3099
3200
|
var React17 = __toESM(require("react"));
|
|
3100
|
-
var
|
|
3201
|
+
var import_react_native19 = require("react-native");
|
|
3101
3202
|
|
|
3102
3203
|
// src/components/primitives/Avatar.tsx
|
|
3103
|
-
var
|
|
3204
|
+
var import_react_native18 = require("react-native");
|
|
3104
3205
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3105
3206
|
function initialsFrom(name) {
|
|
3106
3207
|
var _a, _b;
|
|
@@ -3120,7 +3221,7 @@ function Avatar({
|
|
|
3120
3221
|
const radius = size / 2;
|
|
3121
3222
|
const fallbackBg = fallbackBackgroundColor ?? theme.colors.neutral;
|
|
3122
3223
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3123
|
-
|
|
3224
|
+
import_react_native18.View,
|
|
3124
3225
|
{
|
|
3125
3226
|
style: [
|
|
3126
3227
|
{
|
|
@@ -3135,7 +3236,7 @@ function Avatar({
|
|
|
3135
3236
|
style
|
|
3136
3237
|
],
|
|
3137
3238
|
children: uri ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3138
|
-
|
|
3239
|
+
import_react_native18.Image,
|
|
3139
3240
|
{
|
|
3140
3241
|
source: { uri },
|
|
3141
3242
|
style: [{ width: size, height: size }, imageStyle],
|
|
@@ -3186,7 +3287,7 @@ function CommentRow({ comment, showDivider }) {
|
|
|
3186
3287
|
};
|
|
3187
3288
|
}, [comment.authorId]);
|
|
3188
3289
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
3189
|
-
|
|
3290
|
+
import_react_native19.View,
|
|
3190
3291
|
{
|
|
3191
3292
|
style: {
|
|
3192
3293
|
flexDirection: "row",
|
|
@@ -3197,8 +3298,8 @@ function CommentRow({ comment, showDivider }) {
|
|
|
3197
3298
|
},
|
|
3198
3299
|
children: [
|
|
3199
3300
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Avatar, { size: 32, uri: authorAvatar, name: authorName ?? comment.authorId, style: { marginTop: 6 } }),
|
|
3200
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
3201
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
3301
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native19.View, { style: { flex: 1, minWidth: 0, gap: 4 }, children: [
|
|
3302
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native19.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.sm }, children: [
|
|
3202
3303
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { style: { fontSize: 14, lineHeight: 18, fontWeight: theme.typography.fontWeight.bold, color: theme.colors.text }, children: authorName ?? "Unknown User" }),
|
|
3203
3304
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, children: formatTimeAgo(comment.createdAt) })
|
|
3204
3305
|
] }),
|
|
@@ -3366,13 +3467,13 @@ function useAppDetails(appId) {
|
|
|
3366
3467
|
|
|
3367
3468
|
// src/components/comments/useIosKeyboardSnapFix.ts
|
|
3368
3469
|
var React20 = __toESM(require("react"));
|
|
3369
|
-
var
|
|
3470
|
+
var import_react_native20 = require("react-native");
|
|
3370
3471
|
function useIosKeyboardSnapFix(sheetRef, options) {
|
|
3371
3472
|
const [keyboardVisible, setKeyboardVisible] = React20.useState(false);
|
|
3372
3473
|
React20.useEffect(() => {
|
|
3373
|
-
if (
|
|
3374
|
-
const show =
|
|
3375
|
-
const hide =
|
|
3474
|
+
if (import_react_native20.Platform.OS !== "ios") return;
|
|
3475
|
+
const show = import_react_native20.Keyboard.addListener("keyboardWillShow", () => setKeyboardVisible(true));
|
|
3476
|
+
const hide = import_react_native20.Keyboard.addListener("keyboardWillHide", () => {
|
|
3376
3477
|
var _a;
|
|
3377
3478
|
setKeyboardVisible(false);
|
|
3378
3479
|
const target = (options == null ? void 0 : options.targetIndex) ?? 1;
|
|
@@ -3448,17 +3549,17 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3448
3549
|
onChange: handleChange,
|
|
3449
3550
|
backgroundStyle: {
|
|
3450
3551
|
backgroundColor: theme.scheme === "dark" ? "#0B080F" : "#FFFFFF",
|
|
3451
|
-
borderTopLeftRadius:
|
|
3452
|
-
borderTopRightRadius:
|
|
3552
|
+
borderTopLeftRadius: import_react_native21.Platform.OS === "ios" ? 39 : 16,
|
|
3553
|
+
borderTopRightRadius: import_react_native21.Platform.OS === "ios" ? 39 : 16
|
|
3453
3554
|
},
|
|
3454
3555
|
handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
|
|
3455
3556
|
keyboardBehavior: "interactive",
|
|
3456
3557
|
keyboardBlurBehavior: "restore",
|
|
3457
3558
|
android_keyboardInputMode: "adjustResize",
|
|
3458
3559
|
topInset: insets.top,
|
|
3459
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3560
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: { flex: 1 }, children: [
|
|
3460
3561
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3461
|
-
|
|
3562
|
+
import_react_native21.View,
|
|
3462
3563
|
{
|
|
3463
3564
|
style: {
|
|
3464
3565
|
flexDirection: "row",
|
|
@@ -3494,7 +3595,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3494
3595
|
interactive: true,
|
|
3495
3596
|
effect: "clear",
|
|
3496
3597
|
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3497
|
-
|
|
3598
|
+
import_react_native21.View,
|
|
3498
3599
|
{
|
|
3499
3600
|
style: {
|
|
3500
3601
|
width: 32,
|
|
@@ -3506,7 +3607,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3506
3607
|
opacity: appId ? 1 : 0.5
|
|
3507
3608
|
},
|
|
3508
3609
|
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3509
|
-
|
|
3610
|
+
import_react_native21.Pressable,
|
|
3510
3611
|
{
|
|
3511
3612
|
disabled: !appId,
|
|
3512
3613
|
onPress: () => void handlePlay(),
|
|
@@ -3541,13 +3642,13 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3541
3642
|
},
|
|
3542
3643
|
keyboardShouldPersistTaps: "handled",
|
|
3543
3644
|
children: [
|
|
3544
|
-
loading && comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3645
|
+
loading && comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.ActivityIndicator, {}) }) : comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { variant: "bodyMuted", style: { textAlign: "center" }, children: "No comments yet" }) }) : comments.map((c, idx) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(CommentRow, { comment: c, showDivider: idx < comments.length - 1 }, c.id)),
|
|
3545
3646
|
error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { variant: "captionMuted", style: { marginTop: theme.spacing.lg }, children: "Failed to load comments." }) : null
|
|
3546
3647
|
]
|
|
3547
3648
|
}
|
|
3548
3649
|
),
|
|
3549
3650
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3550
|
-
|
|
3651
|
+
import_react_native21.View,
|
|
3551
3652
|
{
|
|
3552
3653
|
style: {
|
|
3553
3654
|
position: "absolute",
|
|
@@ -3556,7 +3657,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3556
3657
|
bottom: 0,
|
|
3557
3658
|
paddingHorizontal: theme.spacing.lg,
|
|
3558
3659
|
paddingTop: theme.spacing.sm,
|
|
3559
|
-
paddingBottom:
|
|
3660
|
+
paddingBottom: import_react_native21.Platform.OS === "ios" ? keyboardVisible ? theme.spacing.lg : insets.bottom : insets.bottom + 10,
|
|
3560
3661
|
borderTopWidth: 1,
|
|
3561
3662
|
borderTopColor: withAlpha(theme.colors.border, 0.1),
|
|
3562
3663
|
backgroundColor: withAlpha(theme.colors.background, 0.8)
|
|
@@ -3570,7 +3671,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3570
3671
|
useBottomSheetTextInput: true,
|
|
3571
3672
|
onSend: async (text) => {
|
|
3572
3673
|
await create(text);
|
|
3573
|
-
|
|
3674
|
+
import_react_native21.Keyboard.dismiss();
|
|
3574
3675
|
}
|
|
3575
3676
|
}
|
|
3576
3677
|
)
|
|
@@ -3582,16 +3683,16 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3582
3683
|
}
|
|
3583
3684
|
|
|
3584
3685
|
// src/studio/ui/PreviewPanel.tsx
|
|
3585
|
-
var
|
|
3686
|
+
var import_react_native42 = require("react-native");
|
|
3586
3687
|
|
|
3587
3688
|
// src/components/preview/PreviewPage.tsx
|
|
3588
|
-
var
|
|
3689
|
+
var import_react_native22 = require("react-native");
|
|
3589
3690
|
var import_bottom_sheet4 = require("@gorhom/bottom-sheet");
|
|
3590
3691
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3591
3692
|
function PreviewPage({ header, children, contentStyle }) {
|
|
3592
3693
|
const theme = useTheme();
|
|
3593
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
3594
|
-
header ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3694
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_native22.View, { style: { flex: 1 }, children: [
|
|
3695
|
+
header ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native22.View, { children: header }) : null,
|
|
3595
3696
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3596
3697
|
import_bottom_sheet4.BottomSheetScrollView,
|
|
3597
3698
|
{
|
|
@@ -3611,15 +3712,15 @@ function PreviewPage({ header, children, contentStyle }) {
|
|
|
3611
3712
|
}
|
|
3612
3713
|
|
|
3613
3714
|
// src/studio/ui/preview-panel/PreviewPanelHeader.tsx
|
|
3614
|
-
var
|
|
3715
|
+
var import_react_native25 = require("react-native");
|
|
3615
3716
|
|
|
3616
3717
|
// src/components/studio-sheet/StudioSheetHeader.tsx
|
|
3617
|
-
var
|
|
3718
|
+
var import_react_native23 = require("react-native");
|
|
3618
3719
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3619
3720
|
function StudioSheetHeader({ left, center, right, style }) {
|
|
3620
3721
|
const theme = useTheme();
|
|
3621
3722
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
3622
|
-
|
|
3723
|
+
import_react_native23.View,
|
|
3623
3724
|
{
|
|
3624
3725
|
style: [
|
|
3625
3726
|
{
|
|
@@ -3632,9 +3733,9 @@ function StudioSheetHeader({ left, center, right, style }) {
|
|
|
3632
3733
|
style
|
|
3633
3734
|
],
|
|
3634
3735
|
children: [
|
|
3635
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3636
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3637
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3736
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native23.View, { style: { flexDirection: "row", alignItems: "center" }, children: left }),
|
|
3737
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native23.View, { style: { flex: 1, alignItems: "center" }, children: center }),
|
|
3738
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native23.View, { style: { flexDirection: "row", alignItems: "center" }, children: right })
|
|
3638
3739
|
]
|
|
3639
3740
|
}
|
|
3640
3741
|
);
|
|
@@ -3642,7 +3743,7 @@ function StudioSheetHeader({ left, center, right, style }) {
|
|
|
3642
3743
|
|
|
3643
3744
|
// src/components/studio-sheet/StudioSheetHeaderIconButton.tsx
|
|
3644
3745
|
var React22 = __toESM(require("react"));
|
|
3645
|
-
var
|
|
3746
|
+
var import_react_native24 = require("react-native");
|
|
3646
3747
|
var import_liquid_glass5 = require("@callstack/liquid-glass");
|
|
3647
3748
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3648
3749
|
function StudioSheetHeaderIconButton({
|
|
@@ -3661,14 +3762,14 @@ function StudioSheetHeaderIconButton({
|
|
|
3661
3762
|
const glassFallbackBg = theme.scheme === "dark" ? "#18181B" : "#F6F6F6";
|
|
3662
3763
|
const glassInnerBg = intent === "danger" ? theme.colors.danger : theme.colors.primary;
|
|
3663
3764
|
const resolvedOpacity = disabled ? 0.6 : pressed ? 0.9 : 1;
|
|
3664
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3765
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native24.View, { style, children: appearance === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3665
3766
|
import_liquid_glass5.LiquidGlassView,
|
|
3666
3767
|
{
|
|
3667
3768
|
style: [{ borderRadius: 100 }, !import_liquid_glass5.isLiquidGlassSupported && { backgroundColor: glassFallbackBg }],
|
|
3668
3769
|
interactive: true,
|
|
3669
3770
|
effect: "clear",
|
|
3670
3771
|
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3671
|
-
|
|
3772
|
+
import_react_native24.View,
|
|
3672
3773
|
{
|
|
3673
3774
|
style: {
|
|
3674
3775
|
width: size,
|
|
@@ -3680,7 +3781,7 @@ function StudioSheetHeaderIconButton({
|
|
|
3680
3781
|
opacity: resolvedOpacity
|
|
3681
3782
|
},
|
|
3682
3783
|
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3683
|
-
|
|
3784
|
+
import_react_native24.Pressable,
|
|
3684
3785
|
{
|
|
3685
3786
|
accessibilityRole: "button",
|
|
3686
3787
|
accessibilityLabel,
|
|
@@ -3699,7 +3800,7 @@ function StudioSheetHeaderIconButton({
|
|
|
3699
3800
|
)
|
|
3700
3801
|
}
|
|
3701
3802
|
) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3702
|
-
|
|
3803
|
+
import_react_native24.View,
|
|
3703
3804
|
{
|
|
3704
3805
|
style: {
|
|
3705
3806
|
width: size,
|
|
@@ -3711,7 +3812,7 @@ function StudioSheetHeaderIconButton({
|
|
|
3711
3812
|
opacity: resolvedOpacity
|
|
3712
3813
|
},
|
|
3713
3814
|
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3714
|
-
|
|
3815
|
+
import_react_native24.Pressable,
|
|
3715
3816
|
{
|
|
3716
3817
|
accessibilityRole: "button",
|
|
3717
3818
|
accessibilityLabel,
|
|
@@ -3738,7 +3839,7 @@ function PreviewPanelHeader({ isOwner, onClose, onNavigateHome, onGoToChat }) {
|
|
|
3738
3839
|
{
|
|
3739
3840
|
left: onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", appearance: "glass", intent: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IconHome, { size: 20, colorToken: "onPrimary" }) }) : null,
|
|
3740
3841
|
center: null,
|
|
3741
|
-
right: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
3842
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native25.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
3742
3843
|
isOwner ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3743
3844
|
StudioSheetHeaderIconButton,
|
|
3744
3845
|
{
|
|
@@ -3757,10 +3858,10 @@ function PreviewPanelHeader({ isOwner, onClose, onNavigateHome, onGoToChat }) {
|
|
|
3757
3858
|
}
|
|
3758
3859
|
|
|
3759
3860
|
// src/components/preview/PreviewHeroCard.tsx
|
|
3760
|
-
var
|
|
3861
|
+
var import_react_native27 = require("react-native");
|
|
3761
3862
|
|
|
3762
3863
|
// src/components/primitives/Surface.tsx
|
|
3763
|
-
var
|
|
3864
|
+
var import_react_native26 = require("react-native");
|
|
3764
3865
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3765
3866
|
function backgroundFor(variant, theme) {
|
|
3766
3867
|
const { colors } = theme;
|
|
@@ -3779,7 +3880,7 @@ function backgroundFor(variant, theme) {
|
|
|
3779
3880
|
function Surface({ variant = "surface", border = false, style, ...props }) {
|
|
3780
3881
|
const theme = useTheme();
|
|
3781
3882
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3782
|
-
|
|
3883
|
+
import_react_native26.View,
|
|
3783
3884
|
{
|
|
3784
3885
|
...props,
|
|
3785
3886
|
style: [
|
|
@@ -3835,11 +3936,11 @@ function PreviewHeroCard({
|
|
|
3835
3936
|
},
|
|
3836
3937
|
style
|
|
3837
3938
|
],
|
|
3838
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
3839
|
-
background ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3840
|
-
image ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3841
|
-
overlayTopLeft ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3842
|
-
overlayBottom ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3939
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native27.View, { style: { flex: 1 }, children: [
|
|
3940
|
+
background ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native27.View, { style: { position: "absolute", inset: 0 }, children: background }) : null,
|
|
3941
|
+
image ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native27.View, { style: { position: "absolute", inset: 0 }, children: image }) : null,
|
|
3942
|
+
overlayTopLeft ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native27.View, { style: { position: "absolute", top: theme.spacing.sm, left: theme.spacing.sm, zIndex: 2 }, children: overlayTopLeft }) : null,
|
|
3943
|
+
overlayBottom ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native27.View, { style: { flex: 1, justifyContent: "flex-end" }, children: overlayBottom }) : null
|
|
3843
3944
|
] })
|
|
3844
3945
|
}
|
|
3845
3946
|
);
|
|
@@ -3847,20 +3948,20 @@ function PreviewHeroCard({
|
|
|
3847
3948
|
|
|
3848
3949
|
// src/components/preview/PreviewPlaceholder.tsx
|
|
3849
3950
|
var React23 = __toESM(require("react"));
|
|
3850
|
-
var
|
|
3951
|
+
var import_react_native28 = require("react-native");
|
|
3851
3952
|
var import_expo_linear_gradient2 = require("expo-linear-gradient");
|
|
3852
3953
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
3853
3954
|
function PreviewPlaceholder({ visible, style }) {
|
|
3854
3955
|
if (!visible) return null;
|
|
3855
|
-
const opacityAnim = React23.useRef(new
|
|
3956
|
+
const opacityAnim = React23.useRef(new import_react_native28.Animated.Value(0)).current;
|
|
3856
3957
|
React23.useEffect(() => {
|
|
3857
3958
|
if (!visible) return;
|
|
3858
|
-
const animation =
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3959
|
+
const animation = import_react_native28.Animated.loop(
|
|
3960
|
+
import_react_native28.Animated.sequence([
|
|
3961
|
+
import_react_native28.Animated.timing(opacityAnim, { toValue: 1, duration: 1500, useNativeDriver: true }),
|
|
3962
|
+
import_react_native28.Animated.timing(opacityAnim, { toValue: 2, duration: 1500, useNativeDriver: true }),
|
|
3963
|
+
import_react_native28.Animated.timing(opacityAnim, { toValue: 3, duration: 1500, useNativeDriver: true }),
|
|
3964
|
+
import_react_native28.Animated.timing(opacityAnim, { toValue: 0, duration: 1500, useNativeDriver: true })
|
|
3864
3965
|
])
|
|
3865
3966
|
);
|
|
3866
3967
|
animation.start();
|
|
@@ -3871,7 +3972,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3871
3972
|
const opacity3 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 1, 0] });
|
|
3872
3973
|
const opacity4 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 0, 1] });
|
|
3873
3974
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
3874
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3975
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native28.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3875
3976
|
import_expo_linear_gradient2.LinearGradient,
|
|
3876
3977
|
{
|
|
3877
3978
|
colors: ["rgba(98, 0, 238, 0.45)", "rgba(168, 85, 247, 0.35)"],
|
|
@@ -3880,7 +3981,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3880
3981
|
style: { width: "100%", height: "100%" }
|
|
3881
3982
|
}
|
|
3882
3983
|
) }),
|
|
3883
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3984
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native28.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity2 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3884
3985
|
import_expo_linear_gradient2.LinearGradient,
|
|
3885
3986
|
{
|
|
3886
3987
|
colors: ["rgba(168, 85, 247, 0.45)", "rgba(139, 92, 246, 0.35)"],
|
|
@@ -3889,7 +3990,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3889
3990
|
style: { width: "100%", height: "100%" }
|
|
3890
3991
|
}
|
|
3891
3992
|
) }),
|
|
3892
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3993
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native28.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity3 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3893
3994
|
import_expo_linear_gradient2.LinearGradient,
|
|
3894
3995
|
{
|
|
3895
3996
|
colors: ["rgba(139, 92, 246, 0.45)", "rgba(126, 34, 206, 0.35)"],
|
|
@@ -3898,7 +3999,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3898
3999
|
style: { width: "100%", height: "100%" }
|
|
3899
4000
|
}
|
|
3900
4001
|
) }),
|
|
3901
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
4002
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native28.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity4 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3902
4003
|
import_expo_linear_gradient2.LinearGradient,
|
|
3903
4004
|
{
|
|
3904
4005
|
colors: ["rgba(126, 34, 206, 0.45)", "rgba(98, 0, 238, 0.35)"],
|
|
@@ -3911,12 +4012,12 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3911
4012
|
}
|
|
3912
4013
|
|
|
3913
4014
|
// src/components/preview/PreviewImage.tsx
|
|
3914
|
-
var
|
|
4015
|
+
var import_react_native29 = require("react-native");
|
|
3915
4016
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
3916
4017
|
function PreviewImage({ uri, onLoad, style }) {
|
|
3917
4018
|
if (!uri) return null;
|
|
3918
4019
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3919
|
-
|
|
4020
|
+
import_react_native29.Image,
|
|
3920
4021
|
{
|
|
3921
4022
|
source: { uri },
|
|
3922
4023
|
resizeMode: "cover",
|
|
@@ -3927,7 +4028,7 @@ function PreviewImage({ uri, onLoad, style }) {
|
|
|
3927
4028
|
}
|
|
3928
4029
|
|
|
3929
4030
|
// src/components/preview/StatsBar.tsx
|
|
3930
|
-
var
|
|
4031
|
+
var import_react_native30 = require("react-native");
|
|
3931
4032
|
var import_liquid_glass6 = require("@callstack/liquid-glass");
|
|
3932
4033
|
var import_lucide_react_native5 = require("lucide-react-native");
|
|
3933
4034
|
|
|
@@ -3960,7 +4061,7 @@ function StatsBar({
|
|
|
3960
4061
|
const theme = useTheme();
|
|
3961
4062
|
const statsBgColor = theme.scheme === "dark" ? "rgba(24, 24, 27, 0.5)" : "rgba(255, 255, 255, 0.5)";
|
|
3962
4063
|
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3963
|
-
|
|
4064
|
+
import_react_native30.View,
|
|
3964
4065
|
{
|
|
3965
4066
|
style: [
|
|
3966
4067
|
{ position: "absolute", bottom: 12, width: "100%", paddingHorizontal: 12 },
|
|
@@ -3976,15 +4077,15 @@ function StatsBar({
|
|
|
3976
4077
|
!import_liquid_glass6.isLiquidGlassSupported && { backgroundColor: statsBgColor }
|
|
3977
4078
|
],
|
|
3978
4079
|
effect: "clear",
|
|
3979
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
4080
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native30.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16 }, children: [
|
|
3980
4081
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3981
|
-
|
|
4082
|
+
import_react_native30.Pressable,
|
|
3982
4083
|
{
|
|
3983
4084
|
disabled: !onPressLike,
|
|
3984
4085
|
onPress: onPressLike,
|
|
3985
4086
|
hitSlop: 8,
|
|
3986
4087
|
style: { paddingVertical: 8 },
|
|
3987
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
4088
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native30.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
3988
4089
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3989
4090
|
import_lucide_react_native5.Heart,
|
|
3990
4091
|
{
|
|
@@ -3994,7 +4095,7 @@ function StatsBar({
|
|
|
3994
4095
|
fill: isLiked ? theme.colors.danger : "transparent"
|
|
3995
4096
|
}
|
|
3996
4097
|
),
|
|
3997
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
4098
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native30.View, { style: { width: 4 } }),
|
|
3998
4099
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3999
4100
|
Text,
|
|
4000
4101
|
{
|
|
@@ -4010,22 +4111,22 @@ function StatsBar({
|
|
|
4010
4111
|
}
|
|
4011
4112
|
),
|
|
4012
4113
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
4013
|
-
|
|
4114
|
+
import_react_native30.Pressable,
|
|
4014
4115
|
{
|
|
4015
4116
|
disabled: !onPressComments,
|
|
4016
4117
|
onPress: onPressComments,
|
|
4017
4118
|
hitSlop: 8,
|
|
4018
4119
|
style: { paddingVertical: 8 },
|
|
4019
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
4120
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native30.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4020
4121
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react_native5.MessageCircle, { size: 16, strokeWidth: 2.5, color: "#FFFFFF" }),
|
|
4021
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
4122
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native30.View, { style: { width: 4 } }),
|
|
4022
4123
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: commentCount })
|
|
4023
4124
|
] })
|
|
4024
4125
|
}
|
|
4025
4126
|
),
|
|
4026
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
4027
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
4028
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
4127
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native30.View, { style: { flexDirection: "row", alignItems: "center", paddingVertical: 8 }, children: [
|
|
4128
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native30.View, { style: { transform: [{ scaleY: -1 }] }, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(MergeIcon, { width: 14, height: 14, color: "#FFFFFF" }) }),
|
|
4129
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native30.View, { style: { width: 4 } }),
|
|
4029
4130
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: forkCount })
|
|
4030
4131
|
] })
|
|
4031
4132
|
] })
|
|
@@ -4036,7 +4137,7 @@ function StatsBar({
|
|
|
4036
4137
|
}
|
|
4037
4138
|
|
|
4038
4139
|
// src/components/preview/PreviewStatusBadge.tsx
|
|
4039
|
-
var
|
|
4140
|
+
var import_react_native31 = require("react-native");
|
|
4040
4141
|
var import_lucide_react_native6 = require("lucide-react-native");
|
|
4041
4142
|
|
|
4042
4143
|
// src/data/apps/types.ts
|
|
@@ -4081,7 +4182,7 @@ function PreviewStatusBadge({ status }) {
|
|
|
4081
4182
|
const IconComp = STATUS_ICON[status];
|
|
4082
4183
|
const label = APP_STATUS_LABEL[status] ?? status;
|
|
4083
4184
|
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
4084
|
-
|
|
4185
|
+
import_react_native31.View,
|
|
4085
4186
|
{
|
|
4086
4187
|
style: {
|
|
4087
4188
|
flexDirection: "row",
|
|
@@ -4134,10 +4235,10 @@ function PreviewHeroSection({
|
|
|
4134
4235
|
}
|
|
4135
4236
|
|
|
4136
4237
|
// src/studio/ui/preview-panel/PreviewMetaSection.tsx
|
|
4137
|
-
var
|
|
4238
|
+
var import_react_native33 = require("react-native");
|
|
4138
4239
|
|
|
4139
4240
|
// src/components/preview/PreviewMetaRow.tsx
|
|
4140
|
-
var
|
|
4241
|
+
var import_react_native32 = require("react-native");
|
|
4141
4242
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
4142
4243
|
function PreviewMetaRow({
|
|
4143
4244
|
avatarUri,
|
|
@@ -4149,10 +4250,10 @@ function PreviewMetaRow({
|
|
|
4149
4250
|
style
|
|
4150
4251
|
}) {
|
|
4151
4252
|
const theme = useTheme();
|
|
4152
|
-
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
4153
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
4253
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react_native32.View, { style: [{ alignSelf: "stretch" }, style], children: [
|
|
4254
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react_native32.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4154
4255
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Avatar, { uri: avatarUri, name: creatorName, size: 24, style: { marginRight: theme.spacing.sm } }),
|
|
4155
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
4256
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react_native32.View, { style: { flexDirection: "row", alignItems: "center", flex: 1, minWidth: 0, marginRight: theme.spacing.sm }, children: [
|
|
4156
4257
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4157
4258
|
Text,
|
|
4158
4259
|
{
|
|
@@ -4167,9 +4268,9 @@ function PreviewMetaRow({
|
|
|
4167
4268
|
children: title
|
|
4168
4269
|
}
|
|
4169
4270
|
),
|
|
4170
|
-
tag ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4271
|
+
tag ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_native32.View, { style: { marginLeft: theme.spacing.sm }, children: tag }) : null
|
|
4171
4272
|
] }),
|
|
4172
|
-
rightMetric ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4273
|
+
rightMetric ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_native32.View, { children: rightMetric }) : null
|
|
4173
4274
|
] }),
|
|
4174
4275
|
subtitle ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4175
4276
|
Text,
|
|
@@ -4225,9 +4326,9 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
|
|
|
4225
4326
|
subtitle: app.description,
|
|
4226
4327
|
avatarUri: (creator == null ? void 0 : creator.avatar) ?? null,
|
|
4227
4328
|
creatorName: (creator == null ? void 0 : creator.name) ?? null,
|
|
4228
|
-
tag: isOwner || app.forkedFromAppId ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
4329
|
+
tag: isOwner || app.forkedFromAppId ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_native33.View, { style: { paddingHorizontal: 8, paddingVertical: 2, borderRadius: 999, backgroundColor: "#3700B3" }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Text, { variant: "caption", style: { color: "#fff", fontWeight: theme.typography.fontWeight.semibold }, children: app.forkedFromAppId ? "Remix" : "Owner" }) }) : null,
|
|
4229
4330
|
rightMetric: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
4230
|
-
|
|
4331
|
+
import_react_native33.View,
|
|
4231
4332
|
{
|
|
4232
4333
|
style: {
|
|
4233
4334
|
flexDirection: "row",
|
|
@@ -4261,10 +4362,10 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
|
|
|
4261
4362
|
}
|
|
4262
4363
|
|
|
4263
4364
|
// src/studio/ui/preview-panel/PreviewCustomizeSection.tsx
|
|
4264
|
-
var
|
|
4365
|
+
var import_react_native35 = require("react-native");
|
|
4265
4366
|
|
|
4266
4367
|
// src/studio/ui/preview-panel/PressableCardRow.tsx
|
|
4267
|
-
var
|
|
4368
|
+
var import_react_native34 = require("react-native");
|
|
4268
4369
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
4269
4370
|
function PressableCardRow({
|
|
4270
4371
|
accessibilityLabel,
|
|
@@ -4277,20 +4378,20 @@ function PressableCardRow({
|
|
|
4277
4378
|
style
|
|
4278
4379
|
}) {
|
|
4279
4380
|
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4280
|
-
|
|
4381
|
+
import_react_native34.Pressable,
|
|
4281
4382
|
{
|
|
4282
4383
|
accessibilityRole: "button",
|
|
4283
4384
|
accessibilityLabel,
|
|
4284
4385
|
disabled,
|
|
4285
4386
|
onPress,
|
|
4286
4387
|
style: ({ pressed }) => ({ opacity: disabled ? 0.6 : pressed ? 0.85 : 1 }),
|
|
4287
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Card, { padded: false, border: false, style, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
4388
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Card, { padded: false, border: false, style, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native34.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4288
4389
|
left,
|
|
4289
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
4390
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native34.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4290
4391
|
title,
|
|
4291
4392
|
subtitle ? subtitle : null
|
|
4292
4393
|
] }),
|
|
4293
|
-
right ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4394
|
+
right ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_native34.View, { style: { marginLeft: 16 }, children: right }) : null
|
|
4294
4395
|
] }) })
|
|
4295
4396
|
}
|
|
4296
4397
|
);
|
|
@@ -4332,7 +4433,7 @@ function PreviewCustomizeSection({
|
|
|
4332
4433
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
4333
4434
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SectionTitle, { children: "Customize" }),
|
|
4334
4435
|
showProcessing ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4335
|
-
|
|
4436
|
+
import_react_native35.View,
|
|
4336
4437
|
{
|
|
4337
4438
|
style: {
|
|
4338
4439
|
flexDirection: "row",
|
|
@@ -4346,7 +4447,7 @@ function PreviewCustomizeSection({
|
|
|
4346
4447
|
},
|
|
4347
4448
|
children: [
|
|
4348
4449
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4349
|
-
|
|
4450
|
+
import_react_native35.View,
|
|
4350
4451
|
{
|
|
4351
4452
|
style: {
|
|
4352
4453
|
width: 40,
|
|
@@ -4357,10 +4458,10 @@ function PreviewCustomizeSection({
|
|
|
4357
4458
|
backgroundColor: withAlpha(theme.colors.warning, 0.1),
|
|
4358
4459
|
marginRight: theme.spacing.lg
|
|
4359
4460
|
},
|
|
4360
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4461
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native35.ActivityIndicator, { color: theme.colors.warning, size: "small" })
|
|
4361
4462
|
}
|
|
4362
4463
|
),
|
|
4363
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4464
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native35.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4364
4465
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: app.status === "error" ? "Error" : "Processing" }),
|
|
4365
4466
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: statusDescription(app.status, app.statusError) })
|
|
4366
4467
|
] })
|
|
@@ -4381,7 +4482,7 @@ function PreviewCustomizeSection({
|
|
|
4381
4482
|
marginBottom: theme.spacing.sm
|
|
4382
4483
|
},
|
|
4383
4484
|
left: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4384
|
-
|
|
4485
|
+
import_react_native35.View,
|
|
4385
4486
|
{
|
|
4386
4487
|
style: {
|
|
4387
4488
|
width: 40,
|
|
@@ -4414,7 +4515,7 @@ function PreviewCustomizeSection({
|
|
|
4414
4515
|
marginBottom: theme.spacing.sm
|
|
4415
4516
|
},
|
|
4416
4517
|
left: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4417
|
-
|
|
4518
|
+
import_react_native35.View,
|
|
4418
4519
|
{
|
|
4419
4520
|
style: {
|
|
4420
4521
|
width: 40,
|
|
@@ -4438,16 +4539,16 @@ function PreviewCustomizeSection({
|
|
|
4438
4539
|
|
|
4439
4540
|
// src/studio/ui/preview-panel/PreviewCollaborateSection.tsx
|
|
4440
4541
|
var React29 = __toESM(require("react"));
|
|
4441
|
-
var
|
|
4542
|
+
var import_react_native41 = require("react-native");
|
|
4442
4543
|
var import_lucide_react_native9 = require("lucide-react-native");
|
|
4443
4544
|
|
|
4444
4545
|
// src/components/merge-requests/MergeRequestStatusCard.tsx
|
|
4445
4546
|
var React25 = __toESM(require("react"));
|
|
4446
|
-
var
|
|
4547
|
+
var import_react_native37 = require("react-native");
|
|
4447
4548
|
var import_lucide_react_native7 = require("lucide-react-native");
|
|
4448
4549
|
|
|
4449
4550
|
// src/components/primitives/MarkdownText.tsx
|
|
4450
|
-
var
|
|
4551
|
+
var import_react_native36 = require("react-native");
|
|
4451
4552
|
var import_react_native_markdown_display = __toESM(require("react-native-markdown-display"));
|
|
4452
4553
|
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
4453
4554
|
function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
@@ -4460,7 +4561,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
|
4460
4561
|
const codeTextColor = isDark ? "#FFFFFF" : theme.colors.text;
|
|
4461
4562
|
const paragraphBottom = variant === "mergeRequest" ? 8 : 6;
|
|
4462
4563
|
const baseLineHeight = variant === "mergeRequest" ? 22 : 20;
|
|
4463
|
-
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4564
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_react_native36.View, { style, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4464
4565
|
import_react_native_markdown_display.default,
|
|
4465
4566
|
{
|
|
4466
4567
|
style: {
|
|
@@ -4473,7 +4574,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
|
4473
4574
|
paddingHorizontal: variant === "mergeRequest" ? 6 : 4,
|
|
4474
4575
|
paddingVertical: variant === "mergeRequest" ? 2 : 0,
|
|
4475
4576
|
borderRadius: variant === "mergeRequest" ? 6 : 4,
|
|
4476
|
-
fontFamily:
|
|
4577
|
+
fontFamily: import_react_native36.Platform.OS === "ios" ? "Menlo" : "monospace",
|
|
4477
4578
|
fontSize: 13
|
|
4478
4579
|
},
|
|
4479
4580
|
code_block: {
|
|
@@ -4585,15 +4686,15 @@ function MergeRequestStatusCard({
|
|
|
4585
4686
|
const createdIso = toIsoString(mergeRequest.createdAt ?? null);
|
|
4586
4687
|
const headerTimeAgo = updatedIso ? formatTimeAgo(updatedIso) : "";
|
|
4587
4688
|
const createdTimeAgo = createdIso ? formatTimeAgo(createdIso) : "";
|
|
4588
|
-
const rotate = React25.useRef(new
|
|
4689
|
+
const rotate = React25.useRef(new import_react_native37.Animated.Value(expanded ? 1 : 0)).current;
|
|
4589
4690
|
React25.useEffect(() => {
|
|
4590
|
-
|
|
4691
|
+
import_react_native37.Animated.timing(rotate, {
|
|
4591
4692
|
toValue: expanded ? 1 : 0,
|
|
4592
4693
|
duration: 200,
|
|
4593
4694
|
useNativeDriver: true
|
|
4594
4695
|
}).start();
|
|
4595
4696
|
}, [expanded, rotate]);
|
|
4596
|
-
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4697
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native37.Pressable, { onPress: () => setExpanded(!expanded), style: ({ pressed }) => [{ opacity: pressed ? 0.95 : 1 }], children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
4597
4698
|
Card,
|
|
4598
4699
|
{
|
|
4599
4700
|
padded: false,
|
|
@@ -4606,10 +4707,10 @@ function MergeRequestStatusCard({
|
|
|
4606
4707
|
style
|
|
4607
4708
|
],
|
|
4608
4709
|
children: [
|
|
4609
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
4610
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4611
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
4612
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
4710
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native37.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.lg }, children: [
|
|
4711
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native37.View, { style: { width: 40, height: 40, borderRadius: 999, alignItems: "center", justifyContent: "center", backgroundColor: bgColor }, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(StatusIcon, { size: 20, color: iconColor }) }),
|
|
4712
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native37.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4713
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native37.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
4613
4714
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4614
4715
|
Text,
|
|
4615
4716
|
{
|
|
@@ -4628,8 +4729,8 @@ function MergeRequestStatusCard({
|
|
|
4628
4729
|
] }),
|
|
4629
4730
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, numberOfLines: 1, children: mergeRequest.title ?? "Untitled merge request" })
|
|
4630
4731
|
] }),
|
|
4631
|
-
headerRight ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4632
|
-
|
|
4732
|
+
headerRight ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native37.View, { children: headerRight }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4733
|
+
import_react_native37.Animated.View,
|
|
4633
4734
|
{
|
|
4634
4735
|
style: {
|
|
4635
4736
|
transform: [
|
|
@@ -4642,7 +4743,7 @@ function MergeRequestStatusCard({
|
|
|
4642
4743
|
}
|
|
4643
4744
|
)
|
|
4644
4745
|
] }),
|
|
4645
|
-
expanded ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
4746
|
+
expanded ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native37.View, { style: { marginTop: 16, marginLeft: 56 }, children: [
|
|
4646
4747
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4647
4748
|
Text,
|
|
4648
4749
|
{
|
|
@@ -4678,16 +4779,16 @@ function MergeRequestStatusCard({
|
|
|
4678
4779
|
|
|
4679
4780
|
// src/components/merge-requests/ReviewMergeRequestCarousel.tsx
|
|
4680
4781
|
var React28 = __toESM(require("react"));
|
|
4681
|
-
var
|
|
4782
|
+
var import_react_native40 = require("react-native");
|
|
4682
4783
|
|
|
4683
4784
|
// src/components/merge-requests/ReviewMergeRequestCard.tsx
|
|
4684
4785
|
var React27 = __toESM(require("react"));
|
|
4685
|
-
var
|
|
4786
|
+
var import_react_native39 = require("react-native");
|
|
4686
4787
|
var import_lucide_react_native8 = require("lucide-react-native");
|
|
4687
4788
|
|
|
4688
4789
|
// src/components/merge-requests/ReviewMergeRequestActionButton.tsx
|
|
4689
4790
|
var React26 = __toESM(require("react"));
|
|
4690
|
-
var
|
|
4791
|
+
var import_react_native38 = require("react-native");
|
|
4691
4792
|
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
4692
4793
|
function ReviewMergeRequestActionButton({
|
|
4693
4794
|
accessibilityLabel,
|
|
@@ -4704,7 +4805,7 @@ function ReviewMergeRequestActionButton({
|
|
|
4704
4805
|
const paddingVertical = iconOnly ? 0 : 8;
|
|
4705
4806
|
const opacity = disabled ? 0.5 : pressed ? 0.9 : 1;
|
|
4706
4807
|
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
4707
|
-
|
|
4808
|
+
import_react_native38.View,
|
|
4708
4809
|
{
|
|
4709
4810
|
style: {
|
|
4710
4811
|
width,
|
|
@@ -4719,7 +4820,7 @@ function ReviewMergeRequestActionButton({
|
|
|
4719
4820
|
justifyContent: "center"
|
|
4720
4821
|
},
|
|
4721
4822
|
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
4722
|
-
|
|
4823
|
+
import_react_native38.Pressable,
|
|
4723
4824
|
{
|
|
4724
4825
|
accessibilityRole: "button",
|
|
4725
4826
|
accessibilityLabel,
|
|
@@ -4761,12 +4862,12 @@ function ReviewMergeRequestCard({
|
|
|
4761
4862
|
const theme = useTheme();
|
|
4762
4863
|
const status = React27.useMemo(() => getMergeRequestStatusDisplay(mr.status), [mr.status]);
|
|
4763
4864
|
const canAct = mr.status === "open";
|
|
4764
|
-
const rotate = React27.useRef(new
|
|
4865
|
+
const rotate = React27.useRef(new import_react_native39.Animated.Value(isExpanded ? 1 : 0)).current;
|
|
4765
4866
|
React27.useEffect(() => {
|
|
4766
|
-
|
|
4867
|
+
import_react_native39.Animated.timing(rotate, { toValue: isExpanded ? 1 : 0, duration: 200, useNativeDriver: true }).start();
|
|
4767
4868
|
}, [isExpanded, rotate]);
|
|
4768
4869
|
const position = total > 1 ? `${index + 1}/${total}` : "Merge request";
|
|
4769
|
-
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4870
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native39.Pressable, { onPress: onToggle, style: ({ pressed }) => ({ opacity: pressed ? 0.95 : 1 }), children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4770
4871
|
Card,
|
|
4771
4872
|
{
|
|
4772
4873
|
padded: false,
|
|
@@ -4779,9 +4880,9 @@ function ReviewMergeRequestCard({
|
|
|
4779
4880
|
}
|
|
4780
4881
|
],
|
|
4781
4882
|
children: [
|
|
4782
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4883
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [
|
|
4783
4884
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Avatar, { size: 40, uri: (creator == null ? void 0 : creator.avatar) ?? null, name: (creator == null ? void 0 : creator.name) ?? void 0 }),
|
|
4784
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4885
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4785
4886
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4786
4887
|
Text,
|
|
4787
4888
|
{
|
|
@@ -4797,7 +4898,7 @@ function ReviewMergeRequestCard({
|
|
|
4797
4898
|
] })
|
|
4798
4899
|
] }),
|
|
4799
4900
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4800
|
-
|
|
4901
|
+
import_react_native39.Animated.View,
|
|
4801
4902
|
{
|
|
4802
4903
|
style: {
|
|
4803
4904
|
transform: [{ rotate: rotate.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "180deg"] }) }]
|
|
@@ -4806,7 +4907,7 @@ function ReviewMergeRequestCard({
|
|
|
4806
4907
|
}
|
|
4807
4908
|
)
|
|
4808
4909
|
] }),
|
|
4809
|
-
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4910
|
+
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { marginTop: 16 }, children: [
|
|
4810
4911
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4811
4912
|
Text,
|
|
4812
4913
|
{
|
|
@@ -4824,9 +4925,9 @@ function ReviewMergeRequestCard({
|
|
|
4824
4925
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginBottom: 12 }, children: creator ? `${creator.approvedOpenedMergeRequests} approved merge${creator.approvedOpenedMergeRequests !== 1 ? "s" : ""}` : "Loading stats..." }),
|
|
4825
4926
|
mr.description ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(MarkdownText, { markdown: mr.description, variant: "mergeRequest" }) : null
|
|
4826
4927
|
] }) : null,
|
|
4827
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4828
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4829
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4928
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native39.View, { style: { height: 1, backgroundColor: withAlpha(theme.colors.borderStrong, 0.5), marginTop: 12, marginBottom: 12 } }),
|
|
4929
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
4930
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", gap: 8 }, children: [
|
|
4830
4931
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4831
4932
|
ReviewMergeRequestActionButton,
|
|
4832
4933
|
{
|
|
@@ -4835,7 +4936,7 @@ function ReviewMergeRequestCard({
|
|
|
4835
4936
|
disabled: !canAct || isAnyProcessing,
|
|
4836
4937
|
onPress: onReject,
|
|
4837
4938
|
iconOnly: !isExpanded,
|
|
4838
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4939
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4839
4940
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native8.X, { size: 18, color: "#FFFFFF" }),
|
|
4840
4941
|
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Reject" }) : null
|
|
4841
4942
|
] })
|
|
@@ -4849,10 +4950,10 @@ function ReviewMergeRequestCard({
|
|
|
4849
4950
|
disabled: !canAct || isAnyProcessing,
|
|
4850
4951
|
onPress: onApprove,
|
|
4851
4952
|
iconOnly: !isExpanded,
|
|
4852
|
-
children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4853
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4953
|
+
children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4954
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native39.ActivityIndicator, { size: "small", color: "#FFFFFF" }),
|
|
4854
4955
|
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Processing" }) : null
|
|
4855
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4956
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4856
4957
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native8.Check, { size: 18, color: "#FFFFFF" }),
|
|
4857
4958
|
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Approve" }) : null
|
|
4858
4959
|
] })
|
|
@@ -4867,7 +4968,7 @@ function ReviewMergeRequestCard({
|
|
|
4867
4968
|
disabled: isBuilding || isTestingThis,
|
|
4868
4969
|
onPress: onTest,
|
|
4869
4970
|
iconOnly: !isExpanded,
|
|
4870
|
-
children: isTestingThis ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4971
|
+
children: isTestingThis ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native39.ActivityIndicator, { size: "small", color: "#888" }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4871
4972
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native8.Play, { size: 14, color: theme.colors.text }),
|
|
4872
4973
|
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: theme.colors.text, fontWeight: theme.typography.fontWeight.semibold }, children: "Test" }) : null
|
|
4873
4974
|
] })
|
|
@@ -4893,32 +4994,32 @@ function ReviewMergeRequestCarousel({
|
|
|
4893
4994
|
style
|
|
4894
4995
|
}) {
|
|
4895
4996
|
const theme = useTheme();
|
|
4896
|
-
const { width } = (0,
|
|
4997
|
+
const { width } = (0, import_react_native40.useWindowDimensions)();
|
|
4897
4998
|
const [expanded, setExpanded] = React28.useState({});
|
|
4898
|
-
const carouselScrollX = React28.useRef(new
|
|
4999
|
+
const carouselScrollX = React28.useRef(new import_react_native40.Animated.Value(0)).current;
|
|
4899
5000
|
const peekAmount = 24;
|
|
4900
5001
|
const gap = 16;
|
|
4901
5002
|
const cardWidth = React28.useMemo(() => Math.max(1, width - theme.spacing.lg * 2 - peekAmount), [peekAmount, theme.spacing.lg, width]);
|
|
4902
5003
|
const snapInterval = cardWidth + gap;
|
|
4903
5004
|
const dotColor = theme.scheme === "dark" ? "#FFFFFF" : "#000000";
|
|
4904
5005
|
if (mergeRequests.length === 0) return null;
|
|
4905
|
-
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
5006
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native40.View, { style: [{ marginHorizontal: -theme.spacing.lg }, style], children: [
|
|
4906
5007
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4907
|
-
|
|
5008
|
+
import_react_native40.FlatList,
|
|
4908
5009
|
{
|
|
4909
5010
|
horizontal: true,
|
|
4910
5011
|
data: mergeRequests,
|
|
4911
5012
|
keyExtractor: (mr) => mr.id,
|
|
4912
5013
|
showsHorizontalScrollIndicator: false,
|
|
4913
5014
|
contentContainerStyle: { paddingHorizontal: theme.spacing.lg, paddingVertical: theme.spacing.sm },
|
|
4914
|
-
ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5015
|
+
ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.View, { style: { width: gap } }),
|
|
4915
5016
|
snapToAlignment: "start",
|
|
4916
5017
|
decelerationRate: "fast",
|
|
4917
5018
|
snapToInterval: snapInterval,
|
|
4918
5019
|
disableIntervalMomentum: true,
|
|
4919
5020
|
style: { paddingRight: peekAmount },
|
|
4920
|
-
ListFooterComponent: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4921
|
-
onScroll:
|
|
5021
|
+
ListFooterComponent: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.View, { style: { width: peekAmount } }),
|
|
5022
|
+
onScroll: import_react_native40.Animated.event([{ nativeEvent: { contentOffset: { x: carouselScrollX } } }], {
|
|
4922
5023
|
useNativeDriver: false
|
|
4923
5024
|
}),
|
|
4924
5025
|
scrollEventThrottle: 16,
|
|
@@ -4929,7 +5030,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4929
5030
|
const isProcessing = Boolean(processingMrId && processingMrId === item.id);
|
|
4930
5031
|
const isAnyProcessing = Boolean(processingMrId);
|
|
4931
5032
|
const isTestingThis = Boolean(testingMrId && testingMrId === item.id);
|
|
4932
|
-
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5033
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.View, { style: { width: cardWidth }, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4933
5034
|
ReviewMergeRequestCard,
|
|
4934
5035
|
{
|
|
4935
5036
|
mr: item,
|
|
@@ -4950,7 +5051,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4950
5051
|
}
|
|
4951
5052
|
}
|
|
4952
5053
|
),
|
|
4953
|
-
mergeRequests.length >= 1 ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
5054
|
+
mergeRequests.length >= 1 ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.View, { style: { flexDirection: "row", justifyContent: "center", columnGap: 8, marginTop: theme.spacing.md }, children: mergeRequests.map((mr, index) => {
|
|
4954
5055
|
const inputRange = [(index - 1) * snapInterval, index * snapInterval, (index + 1) * snapInterval];
|
|
4955
5056
|
const scale = carouselScrollX.interpolate({
|
|
4956
5057
|
inputRange,
|
|
@@ -4963,7 +5064,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4963
5064
|
extrapolate: "clamp"
|
|
4964
5065
|
});
|
|
4965
5066
|
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4966
|
-
|
|
5067
|
+
import_react_native40.Animated.View,
|
|
4967
5068
|
{
|
|
4968
5069
|
style: {
|
|
4969
5070
|
width: 8,
|
|
@@ -5024,7 +5125,7 @@ function PreviewCollaborateSection({
|
|
|
5024
5125
|
accessibilityLabel: "Submit merge request",
|
|
5025
5126
|
disabled: submittingMr,
|
|
5026
5127
|
onPress: () => {
|
|
5027
|
-
|
|
5128
|
+
import_react_native41.Alert.alert(
|
|
5028
5129
|
"Submit Merge Request",
|
|
5029
5130
|
"Are you sure you want to submit your changes to the original app?",
|
|
5030
5131
|
[
|
|
@@ -5050,7 +5151,7 @@ function PreviewCollaborateSection({
|
|
|
5050
5151
|
marginBottom: theme.spacing.sm
|
|
5051
5152
|
},
|
|
5052
5153
|
left: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5053
|
-
|
|
5154
|
+
import_react_native41.View,
|
|
5054
5155
|
{
|
|
5055
5156
|
style: {
|
|
5056
5157
|
width: 40,
|
|
@@ -5061,7 +5162,7 @@ function PreviewCollaborateSection({
|
|
|
5061
5162
|
backgroundColor: withAlpha("#03DAC6", 0.1),
|
|
5062
5163
|
marginRight: theme.spacing.lg
|
|
5063
5164
|
},
|
|
5064
|
-
children: submittingMr ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5165
|
+
children: submittingMr ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native41.ActivityIndicator, { color: "#03DAC6", size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MergeIcon, { width: 20, height: 20, color: "#03DAC6" })
|
|
5065
5166
|
}
|
|
5066
5167
|
),
|
|
5067
5168
|
title: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Submit your new changes" }),
|
|
@@ -5099,7 +5200,7 @@ function PreviewCollaborateSection({
|
|
|
5099
5200
|
children: "History"
|
|
5100
5201
|
}
|
|
5101
5202
|
),
|
|
5102
|
-
outgoingMergeRequests.map((mr) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5203
|
+
outgoingMergeRequests.map((mr) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native41.View, { style: { marginBottom: theme.spacing.sm }, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MergeRequestStatusCard, { mergeRequest: toMergeRequestSummary(mr) }) }, mr.id))
|
|
5103
5204
|
] }) : null
|
|
5104
5205
|
] });
|
|
5105
5206
|
}
|
|
@@ -5423,9 +5524,9 @@ function PreviewPanel({
|
|
|
5423
5524
|
});
|
|
5424
5525
|
const header = /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PreviewPanelHeader, { isOwner, onClose, onNavigateHome, onGoToChat });
|
|
5425
5526
|
if (loading || !app) {
|
|
5426
|
-
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PreviewPage, { header, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
5427
|
-
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
5428
|
-
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
5527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PreviewPage, { header, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native42.View, { style: { flex: 1, justifyContent: "center", alignItems: "center", padding: 24 }, children: [
|
|
5528
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native42.ActivityIndicator, {}),
|
|
5529
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native42.View, { style: { height: 12 } }),
|
|
5429
5530
|
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Text, { variant: "bodyMuted", children: "Loading app\u2026" })
|
|
5430
5531
|
] }) });
|
|
5431
5532
|
}
|
|
@@ -5482,20 +5583,20 @@ function PreviewPanel({
|
|
|
5482
5583
|
|
|
5483
5584
|
// src/studio/ui/ChatPanel.tsx
|
|
5484
5585
|
var React36 = __toESM(require("react"));
|
|
5485
|
-
var
|
|
5586
|
+
var import_react_native50 = require("react-native");
|
|
5486
5587
|
|
|
5487
5588
|
// src/components/chat/ChatPage.tsx
|
|
5488
5589
|
var React34 = __toESM(require("react"));
|
|
5489
|
-
var
|
|
5590
|
+
var import_react_native46 = require("react-native");
|
|
5490
5591
|
var import_react_native_safe_area_context4 = require("react-native-safe-area-context");
|
|
5491
5592
|
|
|
5492
5593
|
// src/components/chat/ChatMessageList.tsx
|
|
5493
5594
|
var React33 = __toESM(require("react"));
|
|
5494
|
-
var
|
|
5595
|
+
var import_react_native45 = require("react-native");
|
|
5495
5596
|
var import_bottom_sheet5 = require("@gorhom/bottom-sheet");
|
|
5496
5597
|
|
|
5497
5598
|
// src/components/chat/ChatMessageBubble.tsx
|
|
5498
|
-
var
|
|
5599
|
+
var import_react_native43 = require("react-native");
|
|
5499
5600
|
var import_lucide_react_native10 = require("lucide-react-native");
|
|
5500
5601
|
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
5501
5602
|
function ChatMessageBubble({ message, renderContent, style }) {
|
|
@@ -5511,7 +5612,7 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5511
5612
|
const bubbleVariant = isHuman ? "surface" : "surfaceRaised";
|
|
5512
5613
|
const cornerStyle = isHuman ? { borderTopRightRadius: 0 } : { borderTopLeftRadius: 0 };
|
|
5513
5614
|
const bodyColor = metaStatus === "success" ? theme.colors.success : metaStatus === "error" ? theme.colors.danger : void 0;
|
|
5514
|
-
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5615
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native43.View, { style: [align, style], children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5515
5616
|
Surface,
|
|
5516
5617
|
{
|
|
5517
5618
|
variant: bubbleVariant,
|
|
@@ -5526,10 +5627,10 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5526
5627
|
},
|
|
5527
5628
|
cornerStyle
|
|
5528
5629
|
],
|
|
5529
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
5630
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native43.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5530
5631
|
isMergeCompleted ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react_native10.CheckCheck, { size: 16, color: theme.colors.success, style: { marginRight: theme.spacing.sm } }) : null,
|
|
5531
5632
|
isMergeApproved ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react_native10.GitMerge, { size: 16, color: theme.colors.text, style: { marginRight: theme.spacing.sm } }) : null,
|
|
5532
|
-
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5633
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native43.View, { style: { flexShrink: 1, minWidth: 0 }, children: renderContent ? renderContent(message) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(MarkdownText, { markdown: message.content, variant: "chat", bodyColor }) })
|
|
5533
5634
|
] })
|
|
5534
5635
|
}
|
|
5535
5636
|
) });
|
|
@@ -5537,23 +5638,23 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5537
5638
|
|
|
5538
5639
|
// src/components/chat/TypingIndicator.tsx
|
|
5539
5640
|
var React32 = __toESM(require("react"));
|
|
5540
|
-
var
|
|
5641
|
+
var import_react_native44 = require("react-native");
|
|
5541
5642
|
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
5542
5643
|
function TypingIndicator({ style }) {
|
|
5543
5644
|
const theme = useTheme();
|
|
5544
5645
|
const dotColor = theme.colors.textSubtle;
|
|
5545
5646
|
const anims = React32.useMemo(
|
|
5546
|
-
() => [new
|
|
5647
|
+
() => [new import_react_native44.Animated.Value(0.3), new import_react_native44.Animated.Value(0.3), new import_react_native44.Animated.Value(0.3)],
|
|
5547
5648
|
[]
|
|
5548
5649
|
);
|
|
5549
5650
|
React32.useEffect(() => {
|
|
5550
5651
|
const loops = [];
|
|
5551
5652
|
anims.forEach((a, idx) => {
|
|
5552
|
-
const seq =
|
|
5553
|
-
|
|
5554
|
-
|
|
5653
|
+
const seq = import_react_native44.Animated.sequence([
|
|
5654
|
+
import_react_native44.Animated.timing(a, { toValue: 1, duration: 420, useNativeDriver: true, delay: idx * 140 }),
|
|
5655
|
+
import_react_native44.Animated.timing(a, { toValue: 0.3, duration: 420, useNativeDriver: true })
|
|
5555
5656
|
]);
|
|
5556
|
-
const loop =
|
|
5657
|
+
const loop = import_react_native44.Animated.loop(seq);
|
|
5557
5658
|
loops.push(loop);
|
|
5558
5659
|
loop.start();
|
|
5559
5660
|
});
|
|
@@ -5561,8 +5662,8 @@ function TypingIndicator({ style }) {
|
|
|
5561
5662
|
loops.forEach((l) => l.stop());
|
|
5562
5663
|
};
|
|
5563
5664
|
}, [anims]);
|
|
5564
|
-
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5565
|
-
|
|
5665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native44.View, { style: [{ flexDirection: "row", alignItems: "center" }, style], children: anims.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5666
|
+
import_react_native44.Animated.View,
|
|
5566
5667
|
{
|
|
5567
5668
|
style: {
|
|
5568
5669
|
width: 8,
|
|
@@ -5571,7 +5672,7 @@ function TypingIndicator({ style }) {
|
|
|
5571
5672
|
marginHorizontal: 3,
|
|
5572
5673
|
backgroundColor: dotColor,
|
|
5573
5674
|
opacity: a,
|
|
5574
|
-
transform: [{ translateY:
|
|
5675
|
+
transform: [{ translateY: import_react_native44.Animated.multiply(import_react_native44.Animated.subtract(a, 0.3), 2) }]
|
|
5575
5676
|
}
|
|
5576
5677
|
},
|
|
5577
5678
|
i
|
|
@@ -5595,19 +5696,19 @@ var ChatMessageList = React33.forwardRef(
|
|
|
5595
5696
|
const nearBottomRef = React33.useRef(true);
|
|
5596
5697
|
const initialScrollDoneRef = React33.useRef(false);
|
|
5597
5698
|
const lastMessageIdRef = React33.useRef(null);
|
|
5699
|
+
const data = React33.useMemo(() => {
|
|
5700
|
+
return [...messages].reverse();
|
|
5701
|
+
}, [messages]);
|
|
5598
5702
|
const scrollToBottom = React33.useCallback((options) => {
|
|
5599
5703
|
var _a;
|
|
5600
5704
|
const animated = (options == null ? void 0 : options.animated) ?? true;
|
|
5601
|
-
(_a = listRef.current) == null ? void 0 : _a.
|
|
5705
|
+
(_a = listRef.current) == null ? void 0 : _a.scrollToOffset({ offset: 0, animated });
|
|
5602
5706
|
}, []);
|
|
5603
5707
|
React33.useImperativeHandle(ref, () => ({ scrollToBottom }), [scrollToBottom]);
|
|
5604
5708
|
const handleScroll = React33.useCallback(
|
|
5605
5709
|
(e) => {
|
|
5606
5710
|
const { contentOffset, contentSize, layoutMeasurement } = e.nativeEvent;
|
|
5607
|
-
const distanceFromBottom = Math.max(
|
|
5608
|
-
contentSize.height - Math.max(bottomInset, 0) - (contentOffset.y + layoutMeasurement.height),
|
|
5609
|
-
0
|
|
5610
|
-
);
|
|
5711
|
+
const distanceFromBottom = Math.max(contentOffset.y - Math.max(bottomInset, 0), 0);
|
|
5611
5712
|
const isNear = distanceFromBottom <= nearBottomThreshold;
|
|
5612
5713
|
if (nearBottomRef.current !== isNear) {
|
|
5613
5714
|
nearBottomRef.current = isNear;
|
|
@@ -5616,15 +5717,6 @@ var ChatMessageList = React33.forwardRef(
|
|
|
5616
5717
|
},
|
|
5617
5718
|
[bottomInset, nearBottomThreshold, onNearBottomChange]
|
|
5618
5719
|
);
|
|
5619
|
-
React33.useEffect(() => {
|
|
5620
|
-
var _a;
|
|
5621
|
-
if (initialScrollDoneRef.current) return;
|
|
5622
|
-
if (messages.length === 0) return;
|
|
5623
|
-
initialScrollDoneRef.current = true;
|
|
5624
|
-
lastMessageIdRef.current = ((_a = messages[messages.length - 1]) == null ? void 0 : _a.id) ?? null;
|
|
5625
|
-
const id = requestAnimationFrame(() => scrollToBottom({ animated: false }));
|
|
5626
|
-
return () => cancelAnimationFrame(id);
|
|
5627
|
-
}, [messages, scrollToBottom]);
|
|
5628
5720
|
React33.useEffect(() => {
|
|
5629
5721
|
if (!initialScrollDoneRef.current) return;
|
|
5630
5722
|
const lastId = messages.length > 0 ? messages[messages.length - 1].id : null;
|
|
@@ -5642,35 +5734,37 @@ var ChatMessageList = React33.forwardRef(
|
|
|
5642
5734
|
}
|
|
5643
5735
|
return void 0;
|
|
5644
5736
|
}, [showTypingIndicator, scrollToBottom]);
|
|
5645
|
-
React33.useEffect(() => {
|
|
5646
|
-
if (!initialScrollDoneRef.current) return;
|
|
5647
|
-
if (!nearBottomRef.current) return;
|
|
5648
|
-
const id = requestAnimationFrame(() => scrollToBottom({ animated: false }));
|
|
5649
|
-
return () => cancelAnimationFrame(id);
|
|
5650
|
-
}, [bottomInset, scrollToBottom]);
|
|
5651
5737
|
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
5652
5738
|
import_bottom_sheet5.BottomSheetFlatList,
|
|
5653
5739
|
{
|
|
5654
5740
|
ref: listRef,
|
|
5655
|
-
|
|
5741
|
+
inverted: true,
|
|
5742
|
+
data,
|
|
5656
5743
|
keyExtractor: (m) => m.id,
|
|
5657
|
-
keyboardDismissMode: import_react_native44.Platform.OS === "ios" ? "interactive" : "on-drag",
|
|
5658
5744
|
keyboardShouldPersistTaps: "handled",
|
|
5659
5745
|
onScroll: handleScroll,
|
|
5660
5746
|
scrollEventThrottle: 16,
|
|
5661
5747
|
showsVerticalScrollIndicator: false,
|
|
5748
|
+
onContentSizeChange: () => {
|
|
5749
|
+
if (initialScrollDoneRef.current) return;
|
|
5750
|
+
initialScrollDoneRef.current = true;
|
|
5751
|
+
lastMessageIdRef.current = messages.length > 0 ? messages[messages.length - 1].id : null;
|
|
5752
|
+
nearBottomRef.current = true;
|
|
5753
|
+
onNearBottomChange == null ? void 0 : onNearBottomChange(true);
|
|
5754
|
+
requestAnimationFrame(() => scrollToBottom({ animated: false }));
|
|
5755
|
+
},
|
|
5662
5756
|
contentContainerStyle: [
|
|
5663
5757
|
{
|
|
5664
5758
|
paddingHorizontal: theme.spacing.lg,
|
|
5665
|
-
|
|
5666
|
-
paddingBottom: theme.spacing.sm
|
|
5759
|
+
paddingVertical: theme.spacing.sm
|
|
5667
5760
|
},
|
|
5668
5761
|
contentStyle
|
|
5669
5762
|
],
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5763
|
+
ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native45.View, { style: { height: theme.spacing.sm } }),
|
|
5764
|
+
renderItem: ({ item }) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChatMessageBubble, { message: item, renderContent: renderMessageContent }),
|
|
5765
|
+
ListHeaderComponent: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_react_native45.View, { children: [
|
|
5766
|
+
showTypingIndicator ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native45.View, { style: { marginTop: theme.spacing.sm, alignSelf: "flex-start", paddingHorizontal: theme.spacing.lg }, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(TypingIndicator, {}) }) : null,
|
|
5767
|
+
bottomInset > 0 ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native45.View, { style: { height: bottomInset } }) : null
|
|
5674
5768
|
] })
|
|
5675
5769
|
}
|
|
5676
5770
|
);
|
|
@@ -5689,6 +5783,7 @@ function ChatPage({
|
|
|
5689
5783
|
composer,
|
|
5690
5784
|
overlay,
|
|
5691
5785
|
style,
|
|
5786
|
+
composerHorizontalPadding,
|
|
5692
5787
|
onNearBottomChange,
|
|
5693
5788
|
listRef
|
|
5694
5789
|
}) {
|
|
@@ -5697,15 +5792,15 @@ function ChatPage({
|
|
|
5697
5792
|
const [composerHeight, setComposerHeight] = React34.useState(0);
|
|
5698
5793
|
const [keyboardVisible, setKeyboardVisible] = React34.useState(false);
|
|
5699
5794
|
React34.useEffect(() => {
|
|
5700
|
-
if (
|
|
5701
|
-
const show =
|
|
5702
|
-
const hide =
|
|
5795
|
+
if (import_react_native46.Platform.OS !== "ios") return;
|
|
5796
|
+
const show = import_react_native46.Keyboard.addListener("keyboardWillShow", () => setKeyboardVisible(true));
|
|
5797
|
+
const hide = import_react_native46.Keyboard.addListener("keyboardWillHide", () => setKeyboardVisible(false));
|
|
5703
5798
|
return () => {
|
|
5704
5799
|
show.remove();
|
|
5705
5800
|
hide.remove();
|
|
5706
5801
|
};
|
|
5707
5802
|
}, []);
|
|
5708
|
-
const footerBottomPadding =
|
|
5803
|
+
const footerBottomPadding = import_react_native46.Platform.OS === "ios" ? keyboardVisible ? 0 : insets.bottom : insets.bottom + 10;
|
|
5709
5804
|
const overlayBottom = composerHeight + footerBottomPadding + theme.spacing.lg;
|
|
5710
5805
|
const bottomInset = composerHeight + footerBottomPadding + theme.spacing.xl;
|
|
5711
5806
|
const resolvedOverlay = React34.useMemo(() => {
|
|
@@ -5717,12 +5812,12 @@ function ChatPage({
|
|
|
5717
5812
|
style: [prevStyle, { bottom: overlayBottom }]
|
|
5718
5813
|
});
|
|
5719
5814
|
}, [overlay, overlayBottom]);
|
|
5720
|
-
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
5721
|
-
header ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
5722
|
-
topBanner ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
5723
|
-
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
5815
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native46.View, { style: [{ flex: 1 }, style], children: [
|
|
5816
|
+
header ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native46.View, { children: header }) : null,
|
|
5817
|
+
topBanner ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native46.View, { style: { paddingHorizontal: theme.spacing.lg, paddingTop: theme.spacing.sm }, children: topBanner }) : null,
|
|
5818
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native46.View, { style: { flex: 1 }, children: [
|
|
5724
5819
|
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
5725
|
-
|
|
5820
|
+
import_react_native46.View,
|
|
5726
5821
|
{
|
|
5727
5822
|
style: { flex: 1 },
|
|
5728
5823
|
children: [
|
|
@@ -5742,14 +5837,14 @@ function ChatPage({
|
|
|
5742
5837
|
}
|
|
5743
5838
|
),
|
|
5744
5839
|
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
5745
|
-
|
|
5840
|
+
import_react_native46.View,
|
|
5746
5841
|
{
|
|
5747
5842
|
style: {
|
|
5748
5843
|
position: "absolute",
|
|
5749
5844
|
left: 0,
|
|
5750
5845
|
right: 0,
|
|
5751
5846
|
bottom: 0,
|
|
5752
|
-
paddingHorizontal: theme.spacing.
|
|
5847
|
+
paddingHorizontal: composerHorizontalPadding ?? theme.spacing.md,
|
|
5753
5848
|
paddingTop: theme.spacing.sm,
|
|
5754
5849
|
paddingBottom: footerBottomPadding
|
|
5755
5850
|
},
|
|
@@ -5769,7 +5864,7 @@ function ChatPage({
|
|
|
5769
5864
|
|
|
5770
5865
|
// src/components/chat/ScrollToBottomButton.tsx
|
|
5771
5866
|
var React35 = __toESM(require("react"));
|
|
5772
|
-
var
|
|
5867
|
+
var import_react_native47 = require("react-native");
|
|
5773
5868
|
var import_react_native_reanimated2 = __toESM(require("react-native-reanimated"));
|
|
5774
5869
|
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
5775
5870
|
function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
@@ -5800,7 +5895,7 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5800
5895
|
animStyle
|
|
5801
5896
|
],
|
|
5802
5897
|
children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
5803
|
-
|
|
5898
|
+
import_react_native47.View,
|
|
5804
5899
|
{
|
|
5805
5900
|
style: {
|
|
5806
5901
|
width: 44,
|
|
@@ -5819,7 +5914,7 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5819
5914
|
opacity: pressed ? 0.85 : 1
|
|
5820
5915
|
},
|
|
5821
5916
|
children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
5822
|
-
|
|
5917
|
+
import_react_native47.Pressable,
|
|
5823
5918
|
{
|
|
5824
5919
|
onPress,
|
|
5825
5920
|
onPressIn: () => setPressed(true),
|
|
@@ -5836,10 +5931,10 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5836
5931
|
}
|
|
5837
5932
|
|
|
5838
5933
|
// src/components/chat/ChatHeader.tsx
|
|
5839
|
-
var
|
|
5934
|
+
var import_react_native48 = require("react-native");
|
|
5840
5935
|
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
5841
5936
|
function ChatHeader({ left, right, center, style }) {
|
|
5842
|
-
const flattenedStyle =
|
|
5937
|
+
const flattenedStyle = import_react_native48.StyleSheet.flatten([
|
|
5843
5938
|
{
|
|
5844
5939
|
paddingTop: 0
|
|
5845
5940
|
},
|
|
@@ -5857,7 +5952,7 @@ function ChatHeader({ left, right, center, style }) {
|
|
|
5857
5952
|
}
|
|
5858
5953
|
|
|
5859
5954
|
// src/components/chat/ForkNoticeBanner.tsx
|
|
5860
|
-
var
|
|
5955
|
+
var import_react_native49 = require("react-native");
|
|
5861
5956
|
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
5862
5957
|
function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
5863
5958
|
const theme = useTheme();
|
|
@@ -5878,7 +5973,7 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
|
5878
5973
|
},
|
|
5879
5974
|
style
|
|
5880
5975
|
],
|
|
5881
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
5976
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_react_native49.View, { style: { minWidth: 0 }, children: [
|
|
5882
5977
|
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
5883
5978
|
Text,
|
|
5884
5979
|
{
|
|
@@ -5954,11 +6049,11 @@ function ChatPanel({
|
|
|
5954
6049
|
const header = /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
5955
6050
|
ChatHeader,
|
|
5956
6051
|
{
|
|
5957
|
-
left: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
6052
|
+
left: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native50.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5958
6053
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StudioSheetHeaderIconButton, { onPress: onBack, accessibilityLabel: "Back", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconBack, { size: 20, colorToken: "floatingContent" }) }),
|
|
5959
6054
|
onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconHome, { size: 20, colorToken: "floatingContent" }) }) : null
|
|
5960
6055
|
] }),
|
|
5961
|
-
right: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
6056
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native50.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5962
6057
|
onStartDraw ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StudioSheetHeaderIconButton, { onPress: onStartDraw, accessibilityLabel: "Draw", intent: "danger", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconDraw, { size: 20, colorToken: "onDanger" }) }) : null,
|
|
5963
6058
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconClose, { size: 20, colorToken: "floatingContent" }) })
|
|
5964
6059
|
] }),
|
|
@@ -5974,12 +6069,12 @@ function ChatPanel({
|
|
|
5974
6069
|
) : null;
|
|
5975
6070
|
const showMessagesLoading = Boolean(loading) && messages.length === 0 || forking;
|
|
5976
6071
|
if (showMessagesLoading) {
|
|
5977
|
-
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
5978
|
-
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
5979
|
-
topBanner ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
5980
|
-
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
5981
|
-
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
5982
|
-
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
6072
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native50.View, { style: { flex: 1 }, children: [
|
|
6073
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native50.View, { children: header }),
|
|
6074
|
+
topBanner ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native50.View, { style: { paddingHorizontal: 16, paddingTop: 8 }, children: topBanner }) : null,
|
|
6075
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native50.View, { style: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 24, paddingVertical: 12 }, children: [
|
|
6076
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native50.ActivityIndicator, {}),
|
|
6077
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native50.View, { style: { height: 12 } }),
|
|
5983
6078
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Text, { variant: "bodyMuted", children: forking ? "Creating your copy\u2026" : "Loading messages\u2026" })
|
|
5984
6079
|
] })
|
|
5985
6080
|
] });
|
|
@@ -5991,6 +6086,7 @@ function ChatPanel({
|
|
|
5991
6086
|
messages,
|
|
5992
6087
|
showTypingIndicator,
|
|
5993
6088
|
topBanner,
|
|
6089
|
+
composerHorizontalPadding: 0,
|
|
5994
6090
|
listRef,
|
|
5995
6091
|
onNearBottomChange: setNearBottom,
|
|
5996
6092
|
overlay: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
@@ -6021,10 +6117,10 @@ function ChatPanel({
|
|
|
6021
6117
|
|
|
6022
6118
|
// src/components/dialogs/ConfirmMergeRequestDialog.tsx
|
|
6023
6119
|
var React37 = __toESM(require("react"));
|
|
6024
|
-
var
|
|
6120
|
+
var import_react_native52 = require("react-native");
|
|
6025
6121
|
|
|
6026
6122
|
// src/components/primitives/Modal.tsx
|
|
6027
|
-
var
|
|
6123
|
+
var import_react_native51 = require("react-native");
|
|
6028
6124
|
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
6029
6125
|
function Modal({
|
|
6030
6126
|
visible,
|
|
@@ -6035,15 +6131,15 @@ function Modal({
|
|
|
6035
6131
|
}) {
|
|
6036
6132
|
const theme = useTheme();
|
|
6037
6133
|
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
6038
|
-
|
|
6134
|
+
import_react_native51.Modal,
|
|
6039
6135
|
{
|
|
6040
6136
|
visible,
|
|
6041
6137
|
transparent: true,
|
|
6042
6138
|
animationType: "fade",
|
|
6043
6139
|
onRequestClose,
|
|
6044
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
6140
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_react_native51.View, { style: { flex: 1, backgroundColor: theme.colors.backdrop, justifyContent: "center", padding: theme.spacing.lg }, children: [
|
|
6045
6141
|
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
6046
|
-
|
|
6142
|
+
import_react_native51.Pressable,
|
|
6047
6143
|
{
|
|
6048
6144
|
accessibilityRole: "button",
|
|
6049
6145
|
onPress: dismissOnBackdropPress ? onRequestClose : void 0,
|
|
@@ -6098,7 +6194,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6098
6194
|
backgroundColor: theme.colors.background
|
|
6099
6195
|
},
|
|
6100
6196
|
children: [
|
|
6101
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6197
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native52.View, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6102
6198
|
Text,
|
|
6103
6199
|
{
|
|
6104
6200
|
style: {
|
|
@@ -6110,9 +6206,9 @@ function ConfirmMergeRequestDialog({
|
|
|
6110
6206
|
children: "Are you sure you want to approve this merge request?"
|
|
6111
6207
|
}
|
|
6112
6208
|
) }),
|
|
6113
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
6209
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_native52.View, { style: { marginTop: 16 }, children: [
|
|
6114
6210
|
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6115
|
-
|
|
6211
|
+
import_react_native52.View,
|
|
6116
6212
|
{
|
|
6117
6213
|
style: [
|
|
6118
6214
|
fullWidthButtonBase,
|
|
@@ -6122,7 +6218,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6122
6218
|
}
|
|
6123
6219
|
],
|
|
6124
6220
|
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6125
|
-
|
|
6221
|
+
import_react_native52.Pressable,
|
|
6126
6222
|
{
|
|
6127
6223
|
accessibilityRole: "button",
|
|
6128
6224
|
accessibilityLabel: "Approve Merge",
|
|
@@ -6134,9 +6230,9 @@ function ConfirmMergeRequestDialog({
|
|
|
6134
6230
|
)
|
|
6135
6231
|
}
|
|
6136
6232
|
),
|
|
6137
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6233
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native52.View, { style: { height: 8 } }),
|
|
6138
6234
|
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6139
|
-
|
|
6235
|
+
import_react_native52.View,
|
|
6140
6236
|
{
|
|
6141
6237
|
style: [
|
|
6142
6238
|
fullWidthButtonBase,
|
|
@@ -6148,7 +6244,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6148
6244
|
}
|
|
6149
6245
|
],
|
|
6150
6246
|
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6151
|
-
|
|
6247
|
+
import_react_native52.Pressable,
|
|
6152
6248
|
{
|
|
6153
6249
|
accessibilityRole: "button",
|
|
6154
6250
|
accessibilityLabel: isBuilding ? "Preparing\u2026" : "Test edits first",
|
|
@@ -6160,9 +6256,9 @@ function ConfirmMergeRequestDialog({
|
|
|
6160
6256
|
)
|
|
6161
6257
|
}
|
|
6162
6258
|
),
|
|
6163
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6259
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native52.View, { style: { height: 8 } }),
|
|
6164
6260
|
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6165
|
-
|
|
6261
|
+
import_react_native52.View,
|
|
6166
6262
|
{
|
|
6167
6263
|
style: [
|
|
6168
6264
|
fullWidthButtonBase,
|
|
@@ -6173,7 +6269,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6173
6269
|
}
|
|
6174
6270
|
],
|
|
6175
6271
|
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6176
|
-
|
|
6272
|
+
import_react_native52.Pressable,
|
|
6177
6273
|
{
|
|
6178
6274
|
accessibilityRole: "button",
|
|
6179
6275
|
accessibilityLabel: "Cancel",
|
|
@@ -6223,6 +6319,92 @@ function ConfirmMergeFlow({
|
|
|
6223
6319
|
);
|
|
6224
6320
|
}
|
|
6225
6321
|
|
|
6322
|
+
// src/studio/hooks/useOptimisticChatMessages.ts
|
|
6323
|
+
var React38 = __toESM(require("react"));
|
|
6324
|
+
function makeOptimisticId() {
|
|
6325
|
+
return `optimistic:${Date.now().toString(36)}:${Math.random().toString(36).slice(2, 10)}`;
|
|
6326
|
+
}
|
|
6327
|
+
function toEpochMs(createdAt) {
|
|
6328
|
+
if (createdAt == null) return 0;
|
|
6329
|
+
if (typeof createdAt === "number") return createdAt;
|
|
6330
|
+
if (createdAt instanceof Date) return createdAt.getTime();
|
|
6331
|
+
const t = Date.parse(String(createdAt));
|
|
6332
|
+
return Number.isFinite(t) ? t : 0;
|
|
6333
|
+
}
|
|
6334
|
+
function isOptimisticResolvedByServer(chatMessages, o) {
|
|
6335
|
+
if (o.failed) return false;
|
|
6336
|
+
const normalize = (s) => s.trim();
|
|
6337
|
+
let startIndex = -1;
|
|
6338
|
+
if (o.baseServerLastId) {
|
|
6339
|
+
startIndex = chatMessages.findIndex((m) => m.id === o.baseServerLastId);
|
|
6340
|
+
}
|
|
6341
|
+
const candidates = startIndex >= 0 ? chatMessages.slice(startIndex + 1) : chatMessages;
|
|
6342
|
+
const target = normalize(o.content);
|
|
6343
|
+
for (const m of candidates) {
|
|
6344
|
+
if (m.author !== "human") continue;
|
|
6345
|
+
if (normalize(m.content) !== target) continue;
|
|
6346
|
+
const serverMs = toEpochMs(m.createdAt);
|
|
6347
|
+
const optimisticMs = Date.parse(o.createdAtIso);
|
|
6348
|
+
if (Number.isFinite(optimisticMs) && optimisticMs > 0 && serverMs > 0) {
|
|
6349
|
+
if (serverMs + 12e4 < optimisticMs) continue;
|
|
6350
|
+
}
|
|
6351
|
+
return true;
|
|
6352
|
+
}
|
|
6353
|
+
return false;
|
|
6354
|
+
}
|
|
6355
|
+
function useOptimisticChatMessages({
|
|
6356
|
+
threadId,
|
|
6357
|
+
shouldForkOnEdit,
|
|
6358
|
+
chatMessages,
|
|
6359
|
+
onSendChat
|
|
6360
|
+
}) {
|
|
6361
|
+
const [optimisticChat, setOptimisticChat] = React38.useState([]);
|
|
6362
|
+
React38.useEffect(() => {
|
|
6363
|
+
setOptimisticChat([]);
|
|
6364
|
+
}, [threadId]);
|
|
6365
|
+
const messages = React38.useMemo(() => {
|
|
6366
|
+
if (!optimisticChat || optimisticChat.length === 0) return chatMessages;
|
|
6367
|
+
const unresolved = optimisticChat.filter((o) => !isOptimisticResolvedByServer(chatMessages, o));
|
|
6368
|
+
if (unresolved.length === 0) return chatMessages;
|
|
6369
|
+
const optimisticAsChat = unresolved.map((o) => ({
|
|
6370
|
+
id: o.id,
|
|
6371
|
+
author: "human",
|
|
6372
|
+
content: o.content,
|
|
6373
|
+
createdAt: o.createdAtIso,
|
|
6374
|
+
kind: "optimistic",
|
|
6375
|
+
meta: o.failed ? { kind: "optimistic", event: "send.failed", status: "error" } : { kind: "optimistic", event: "send.pending", status: "info" }
|
|
6376
|
+
}));
|
|
6377
|
+
const merged = [...chatMessages, ...optimisticAsChat];
|
|
6378
|
+
merged.sort((a, b) => String(a.createdAt).localeCompare(String(b.createdAt)));
|
|
6379
|
+
return merged;
|
|
6380
|
+
}, [chatMessages, optimisticChat]);
|
|
6381
|
+
React38.useEffect(() => {
|
|
6382
|
+
if (optimisticChat.length === 0) return;
|
|
6383
|
+
setOptimisticChat((prev) => {
|
|
6384
|
+
if (prev.length === 0) return prev;
|
|
6385
|
+
const next = prev.filter((o) => !isOptimisticResolvedByServer(chatMessages, o) || o.failed);
|
|
6386
|
+
return next.length === prev.length ? prev : next;
|
|
6387
|
+
});
|
|
6388
|
+
}, [chatMessages, optimisticChat.length]);
|
|
6389
|
+
const onSend = React38.useCallback(
|
|
6390
|
+
async (text, attachments) => {
|
|
6391
|
+
if (shouldForkOnEdit) {
|
|
6392
|
+
await onSendChat(text, attachments);
|
|
6393
|
+
return;
|
|
6394
|
+
}
|
|
6395
|
+
const createdAtIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
6396
|
+
const baseServerLastId = chatMessages.length > 0 ? chatMessages[chatMessages.length - 1].id : null;
|
|
6397
|
+
const id = makeOptimisticId();
|
|
6398
|
+
setOptimisticChat((prev) => [...prev, { id, content: text, createdAtIso, baseServerLastId, failed: false }]);
|
|
6399
|
+
void Promise.resolve(onSendChat(text, attachments)).catch(() => {
|
|
6400
|
+
setOptimisticChat((prev) => prev.map((m) => m.id === id ? { ...m, failed: true } : m));
|
|
6401
|
+
});
|
|
6402
|
+
},
|
|
6403
|
+
[chatMessages, onSendChat, shouldForkOnEdit]
|
|
6404
|
+
);
|
|
6405
|
+
return { messages, onSend };
|
|
6406
|
+
}
|
|
6407
|
+
|
|
6226
6408
|
// src/studio/ui/StudioOverlay.tsx
|
|
6227
6409
|
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
6228
6410
|
function StudioOverlay({
|
|
@@ -6254,33 +6436,40 @@ function StudioOverlay({
|
|
|
6254
6436
|
onNavigateHome
|
|
6255
6437
|
}) {
|
|
6256
6438
|
const theme = useTheme();
|
|
6257
|
-
const { width } = (0,
|
|
6258
|
-
const [sheetOpen, setSheetOpen] =
|
|
6259
|
-
const [activePage, setActivePage] =
|
|
6260
|
-
const [drawing, setDrawing] =
|
|
6261
|
-
const [chatAttachments, setChatAttachments] =
|
|
6262
|
-
const [commentsAppId, setCommentsAppId] =
|
|
6263
|
-
const [commentsCount, setCommentsCount] =
|
|
6264
|
-
const
|
|
6265
|
-
const
|
|
6439
|
+
const { width } = (0, import_react_native53.useWindowDimensions)();
|
|
6440
|
+
const [sheetOpen, setSheetOpen] = React39.useState(false);
|
|
6441
|
+
const [activePage, setActivePage] = React39.useState("preview");
|
|
6442
|
+
const [drawing, setDrawing] = React39.useState(false);
|
|
6443
|
+
const [chatAttachments, setChatAttachments] = React39.useState([]);
|
|
6444
|
+
const [commentsAppId, setCommentsAppId] = React39.useState(null);
|
|
6445
|
+
const [commentsCount, setCommentsCount] = React39.useState(null);
|
|
6446
|
+
const threadId = (app == null ? void 0 : app.threadId) ?? null;
|
|
6447
|
+
const optimistic = useOptimisticChatMessages({
|
|
6448
|
+
threadId,
|
|
6449
|
+
shouldForkOnEdit,
|
|
6450
|
+
chatMessages,
|
|
6451
|
+
onSendChat
|
|
6452
|
+
});
|
|
6453
|
+
const [confirmMrId, setConfirmMrId] = React39.useState(null);
|
|
6454
|
+
const confirmMr = React39.useMemo(
|
|
6266
6455
|
() => confirmMrId ? incomingMergeRequests.find((m) => m.id === confirmMrId) ?? null : null,
|
|
6267
6456
|
[confirmMrId, incomingMergeRequests]
|
|
6268
6457
|
);
|
|
6269
|
-
const handleSheetOpenChange =
|
|
6458
|
+
const handleSheetOpenChange = React39.useCallback((open) => {
|
|
6270
6459
|
setSheetOpen(open);
|
|
6271
|
-
if (!open)
|
|
6460
|
+
if (!open) import_react_native53.Keyboard.dismiss();
|
|
6272
6461
|
}, []);
|
|
6273
|
-
const closeSheet =
|
|
6462
|
+
const closeSheet = React39.useCallback(() => {
|
|
6274
6463
|
handleSheetOpenChange(false);
|
|
6275
6464
|
}, [handleSheetOpenChange]);
|
|
6276
|
-
const openSheet =
|
|
6277
|
-
const goToChat =
|
|
6465
|
+
const openSheet = React39.useCallback(() => setSheetOpen(true), []);
|
|
6466
|
+
const goToChat = React39.useCallback(() => {
|
|
6278
6467
|
setActivePage("chat");
|
|
6279
6468
|
openSheet();
|
|
6280
6469
|
}, [openSheet]);
|
|
6281
|
-
const backToPreview =
|
|
6282
|
-
if (
|
|
6283
|
-
|
|
6470
|
+
const backToPreview = React39.useCallback(() => {
|
|
6471
|
+
if (import_react_native53.Platform.OS !== "ios") {
|
|
6472
|
+
import_react_native53.Keyboard.dismiss();
|
|
6284
6473
|
setActivePage("preview");
|
|
6285
6474
|
return;
|
|
6286
6475
|
}
|
|
@@ -6292,15 +6481,15 @@ function StudioOverlay({
|
|
|
6292
6481
|
clearTimeout(t);
|
|
6293
6482
|
setActivePage("preview");
|
|
6294
6483
|
};
|
|
6295
|
-
const sub =
|
|
6484
|
+
const sub = import_react_native53.Keyboard.addListener("keyboardDidHide", finalize);
|
|
6296
6485
|
const t = setTimeout(finalize, 350);
|
|
6297
|
-
|
|
6486
|
+
import_react_native53.Keyboard.dismiss();
|
|
6298
6487
|
}, []);
|
|
6299
|
-
const startDraw =
|
|
6488
|
+
const startDraw = React39.useCallback(() => {
|
|
6300
6489
|
setDrawing(true);
|
|
6301
6490
|
closeSheet();
|
|
6302
6491
|
}, [closeSheet]);
|
|
6303
|
-
const handleDrawCapture =
|
|
6492
|
+
const handleDrawCapture = React39.useCallback(
|
|
6304
6493
|
(dataUrl) => {
|
|
6305
6494
|
setChatAttachments((prev) => [...prev, dataUrl]);
|
|
6306
6495
|
setDrawing(false);
|
|
@@ -6309,7 +6498,7 @@ function StudioOverlay({
|
|
|
6309
6498
|
},
|
|
6310
6499
|
[openSheet]
|
|
6311
6500
|
);
|
|
6312
|
-
const toggleSheet =
|
|
6501
|
+
const toggleSheet = React39.useCallback(async () => {
|
|
6313
6502
|
if (!sheetOpen) {
|
|
6314
6503
|
const shouldExitTest = Boolean(testingMrId) || isTesting;
|
|
6315
6504
|
if (shouldExitTest) {
|
|
@@ -6321,7 +6510,7 @@ function StudioOverlay({
|
|
|
6321
6510
|
closeSheet();
|
|
6322
6511
|
}
|
|
6323
6512
|
}, [closeSheet, isTesting, onRestoreBase, sheetOpen, testingMrId]);
|
|
6324
|
-
const handleTestMr =
|
|
6513
|
+
const handleTestMr = React39.useCallback(
|
|
6325
6514
|
async (mr) => {
|
|
6326
6515
|
if (!onTestMr) return;
|
|
6327
6516
|
await onTestMr(mr);
|
|
@@ -6365,7 +6554,7 @@ function StudioOverlay({
|
|
|
6365
6554
|
chat: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6366
6555
|
ChatPanel,
|
|
6367
6556
|
{
|
|
6368
|
-
messages:
|
|
6557
|
+
messages: optimistic.messages,
|
|
6369
6558
|
showTypingIndicator: chatShowTypingIndicator,
|
|
6370
6559
|
loading: chatLoading,
|
|
6371
6560
|
sendDisabled: chatSendDisabled,
|
|
@@ -6380,7 +6569,7 @@ function StudioOverlay({
|
|
|
6380
6569
|
onClose: closeSheet,
|
|
6381
6570
|
onNavigateHome,
|
|
6382
6571
|
onStartDraw: startDraw,
|
|
6383
|
-
onSend:
|
|
6572
|
+
onSend: optimistic.onSend
|
|
6384
6573
|
}
|
|
6385
6574
|
)
|
|
6386
6575
|
}
|
|
@@ -6393,7 +6582,7 @@ function StudioOverlay({
|
|
|
6393
6582
|
badgeCount: incomingMergeRequests.length,
|
|
6394
6583
|
onPress: toggleSheet,
|
|
6395
6584
|
isLoading: (app == null ? void 0 : app.status) === "editing",
|
|
6396
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6585
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react_native53.View, { style: { width: 28, height: 28, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(MergeIcon, { width: 24, height: 24, color: theme.colors.floatingContent }) })
|
|
6397
6586
|
}
|
|
6398
6587
|
),
|
|
6399
6588
|
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
@@ -6439,16 +6628,16 @@ function ComergeStudio({
|
|
|
6439
6628
|
onNavigateHome,
|
|
6440
6629
|
style
|
|
6441
6630
|
}) {
|
|
6442
|
-
const [activeAppId, setActiveAppId] =
|
|
6443
|
-
const [runtimeAppId, setRuntimeAppId] =
|
|
6444
|
-
const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] =
|
|
6445
|
-
const platform =
|
|
6446
|
-
|
|
6631
|
+
const [activeAppId, setActiveAppId] = React40.useState(appId);
|
|
6632
|
+
const [runtimeAppId, setRuntimeAppId] = React40.useState(appId);
|
|
6633
|
+
const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] = React40.useState(null);
|
|
6634
|
+
const platform = React40.useMemo(() => import_react_native54.Platform.OS === "ios" ? "ios" : "android", []);
|
|
6635
|
+
React40.useEffect(() => {
|
|
6447
6636
|
setActiveAppId(appId);
|
|
6448
6637
|
setRuntimeAppId(appId);
|
|
6449
6638
|
setPendingRuntimeTargetAppId(null);
|
|
6450
6639
|
}, [appId]);
|
|
6451
|
-
const captureTargetRef =
|
|
6640
|
+
const captureTargetRef = React40.useRef(null);
|
|
6452
6641
|
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(StudioBootstrap, { apiKey, children: ({ userId }) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_bottom_sheet6.BottomSheetModalProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
6453
6642
|
ComergeStudioInner,
|
|
6454
6643
|
{
|
|
@@ -6484,11 +6673,11 @@ function ComergeStudioInner({
|
|
|
6484
6673
|
const { app, loading: appLoading } = useApp(activeAppId);
|
|
6485
6674
|
const { app: runtimeAppFromHook } = useApp(runtimeAppId, { enabled: runtimeAppId !== activeAppId });
|
|
6486
6675
|
const runtimeApp = runtimeAppId === activeAppId ? app : runtimeAppFromHook;
|
|
6487
|
-
const sawEditingOnPendingTargetRef =
|
|
6488
|
-
|
|
6676
|
+
const sawEditingOnPendingTargetRef = React40.useRef(false);
|
|
6677
|
+
React40.useEffect(() => {
|
|
6489
6678
|
sawEditingOnPendingTargetRef.current = false;
|
|
6490
6679
|
}, [pendingRuntimeTargetAppId]);
|
|
6491
|
-
|
|
6680
|
+
React40.useEffect(() => {
|
|
6492
6681
|
if (!pendingRuntimeTargetAppId) return;
|
|
6493
6682
|
if (activeAppId !== pendingRuntimeTargetAppId) return;
|
|
6494
6683
|
if ((app == null ? void 0 : app.status) === "editing") {
|
|
@@ -6505,13 +6694,38 @@ function ComergeStudioInner({
|
|
|
6505
6694
|
platform,
|
|
6506
6695
|
canRequestLatest: (runtimeApp == null ? void 0 : runtimeApp.status) === "ready"
|
|
6507
6696
|
});
|
|
6697
|
+
const sawEditingOnActiveAppRef = React40.useRef(false);
|
|
6698
|
+
const [showPostEditPreparing, setShowPostEditPreparing] = React40.useState(false);
|
|
6699
|
+
React40.useEffect(() => {
|
|
6700
|
+
sawEditingOnActiveAppRef.current = false;
|
|
6701
|
+
setShowPostEditPreparing(false);
|
|
6702
|
+
}, [activeAppId]);
|
|
6703
|
+
React40.useEffect(() => {
|
|
6704
|
+
if (!(app == null ? void 0 : app.id)) return;
|
|
6705
|
+
if (app.status === "editing") {
|
|
6706
|
+
sawEditingOnActiveAppRef.current = true;
|
|
6707
|
+
setShowPostEditPreparing(false);
|
|
6708
|
+
return;
|
|
6709
|
+
}
|
|
6710
|
+
if (app.status === "ready" && sawEditingOnActiveAppRef.current) {
|
|
6711
|
+
setShowPostEditPreparing(true);
|
|
6712
|
+
sawEditingOnActiveAppRef.current = false;
|
|
6713
|
+
}
|
|
6714
|
+
}, [app == null ? void 0 : app.id, app == null ? void 0 : app.status]);
|
|
6715
|
+
React40.useEffect(() => {
|
|
6716
|
+
if (!showPostEditPreparing) return;
|
|
6717
|
+
const stillProcessingBaseBundle = bundle.loading && bundle.loadingMode === "base" && !bundle.isTesting;
|
|
6718
|
+
if (!stillProcessingBaseBundle) {
|
|
6719
|
+
setShowPostEditPreparing(false);
|
|
6720
|
+
}
|
|
6721
|
+
}, [showPostEditPreparing, bundle.loading, bundle.loadingMode, bundle.isTesting]);
|
|
6508
6722
|
const threadId = (app == null ? void 0 : app.threadId) ?? "";
|
|
6509
6723
|
const thread = useThreadMessages(threadId);
|
|
6510
6724
|
const mergeRequests = useMergeRequests({ appId: activeAppId });
|
|
6511
|
-
const hasOpenOutgoingMr =
|
|
6725
|
+
const hasOpenOutgoingMr = React40.useMemo(() => {
|
|
6512
6726
|
return mergeRequests.lists.outgoing.some((mr) => mr.status === "open");
|
|
6513
6727
|
}, [mergeRequests.lists.outgoing]);
|
|
6514
|
-
const incomingReviewMrs =
|
|
6728
|
+
const incomingReviewMrs = React40.useMemo(() => {
|
|
6515
6729
|
if (!userId) return mergeRequests.lists.incoming;
|
|
6516
6730
|
return mergeRequests.lists.incoming.filter((mr) => mr.createdBy !== userId);
|
|
6517
6731
|
}, [mergeRequests.lists.incoming, userId]);
|
|
@@ -6533,17 +6747,25 @@ function ComergeStudioInner({
|
|
|
6533
6747
|
uploadAttachments: uploader.uploadBase64Images
|
|
6534
6748
|
});
|
|
6535
6749
|
const chatSendDisabled = hasNoOutcomeAfterLastHuman(thread.raw);
|
|
6536
|
-
const [processingMrId, setProcessingMrId] =
|
|
6537
|
-
const [testingMrId, setTestingMrId] =
|
|
6538
|
-
const chatShowTypingIndicator =
|
|
6750
|
+
const [processingMrId, setProcessingMrId] = React40.useState(null);
|
|
6751
|
+
const [testingMrId, setTestingMrId] = React40.useState(null);
|
|
6752
|
+
const chatShowTypingIndicator = React40.useMemo(() => {
|
|
6539
6753
|
var _a;
|
|
6540
6754
|
if (!thread.raw || thread.raw.length === 0) return false;
|
|
6541
6755
|
const last = thread.raw[thread.raw.length - 1];
|
|
6542
6756
|
const payloadType = typeof ((_a = last.payload) == null ? void 0 : _a.type) === "string" ? String(last.payload.type) : void 0;
|
|
6543
6757
|
return payloadType !== "outcome";
|
|
6544
6758
|
}, [thread.raw]);
|
|
6545
|
-
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
6546
|
-
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
6759
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_react_native54.View, { style: [{ flex: 1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_react_native54.View, { ref: captureTargetRef, style: { flex: 1 }, collapsable: false, children: [
|
|
6760
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
6761
|
+
RuntimeRenderer,
|
|
6762
|
+
{
|
|
6763
|
+
appKey,
|
|
6764
|
+
bundlePath: bundle.bundlePath,
|
|
6765
|
+
forcePreparing: showPostEditPreparing,
|
|
6766
|
+
renderToken: bundle.renderToken
|
|
6767
|
+
}
|
|
6768
|
+
),
|
|
6547
6769
|
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
6548
6770
|
StudioOverlay,
|
|
6549
6771
|
{
|