@comergehq/studio 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1120 -863
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +911 -654
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/chat/ChatComposer.tsx +9 -7
- package/src/components/chat/ChatMessageList.tsx +21 -35
- package/src/components/chat/ChatPage.tsx +3 -1
- package/src/components/comments/AppCommentsSheet.tsx +6 -6
- package/src/components/floating-draggable-button/FloatingDraggableButton.tsx +12 -27
- package/src/components/preview/StatsBar.tsx +4 -3
- package/src/components/studio-sheet/StudioBottomSheet.tsx +3 -3
- package/src/components/studio-sheet/StudioSheetBackground.tsx +3 -2
- package/src/components/studio-sheet/StudioSheetHeaderIconButton.tsx +7 -5
- package/src/components/utils/ResettableLiquidGlassView.tsx +28 -0
- package/src/components/utils/liquidGlassReset.tsx +36 -0
- package/src/studio/ComergeStudio.tsx +51 -15
- package/src/studio/hooks/useAttachmentUpload.ts +51 -5
- package/src/studio/hooks/useBundleManager.ts +91 -17
- package/src/studio/hooks/useOptimisticChatMessages.ts +128 -0
- package/src/studio/ui/ChatPanel.tsx +1 -0
- package/src/studio/ui/RuntimeRenderer.tsx +7 -2
- package/src/studio/ui/StudioOverlay.tsx +11 -2
package/dist/index.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 React42 = __toESM(require("react"));
|
|
40
|
+
var import_react_native55 = 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,25 +1812,76 @@ function RuntimeRenderer({ appKey, bundlePath, renderToken, style }) {
|
|
|
1711
1812
|
}
|
|
1712
1813
|
|
|
1713
1814
|
// src/studio/ui/StudioOverlay.tsx
|
|
1714
|
-
var
|
|
1715
|
-
var
|
|
1815
|
+
var React41 = __toESM(require("react"));
|
|
1816
|
+
var import_react_native54 = require("react-native");
|
|
1716
1817
|
|
|
1717
1818
|
// src/components/studio-sheet/StudioBottomSheet.tsx
|
|
1718
|
-
var
|
|
1719
|
-
var
|
|
1819
|
+
var React11 = __toESM(require("react"));
|
|
1820
|
+
var import_react_native9 = 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_native8 = require("react-native");
|
|
1826
|
+
var import_liquid_glass2 = require("@callstack/liquid-glass");
|
|
1827
|
+
|
|
1828
|
+
// src/components/utils/ResettableLiquidGlassView.tsx
|
|
1829
|
+
var React10 = __toESM(require("react"));
|
|
1725
1830
|
var import_liquid_glass = require("@callstack/liquid-glass");
|
|
1831
|
+
|
|
1832
|
+
// src/components/utils/liquidGlassReset.tsx
|
|
1833
|
+
var React9 = __toESM(require("react"));
|
|
1834
|
+
var import_react_native7 = require("react-native");
|
|
1726
1835
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1836
|
+
var LiquidGlassResetContext = React9.createContext(0);
|
|
1837
|
+
function LiquidGlassResetProvider({
|
|
1838
|
+
children,
|
|
1839
|
+
resetTriggers = []
|
|
1840
|
+
}) {
|
|
1841
|
+
const [token, setToken] = React9.useState(0);
|
|
1842
|
+
React9.useEffect(() => {
|
|
1843
|
+
if (import_react_native7.Platform.OS !== "ios") return;
|
|
1844
|
+
const onChange = (state) => {
|
|
1845
|
+
if (state === "active") setToken((t) => t + 1);
|
|
1846
|
+
};
|
|
1847
|
+
const sub = import_react_native7.AppState.addEventListener("change", onChange);
|
|
1848
|
+
return () => sub.remove();
|
|
1849
|
+
}, []);
|
|
1850
|
+
React9.useEffect(() => {
|
|
1851
|
+
setToken((t) => t + 1);
|
|
1852
|
+
}, resetTriggers);
|
|
1853
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LiquidGlassResetContext.Provider, { value: token, children });
|
|
1854
|
+
}
|
|
1855
|
+
function useLiquidGlassResetToken() {
|
|
1856
|
+
return React9.useContext(LiquidGlassResetContext);
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
// src/components/utils/ResettableLiquidGlassView.tsx
|
|
1860
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1861
|
+
function ResettableLiquidGlassView({ children, ...props }) {
|
|
1862
|
+
const token = useLiquidGlassResetToken();
|
|
1863
|
+
const [layoutBootKey, setLayoutBootKey] = React10.useState(0);
|
|
1864
|
+
const sawNonZeroLayoutRef = React10.useRef(false);
|
|
1865
|
+
const onLayout = (e) => {
|
|
1866
|
+
var _a;
|
|
1867
|
+
(_a = props.onLayout) == null ? void 0 : _a.call(props, e);
|
|
1868
|
+
const { width, height } = e.nativeEvent.layout;
|
|
1869
|
+
if (width > 0 && height > 0 && !sawNonZeroLayoutRef.current) {
|
|
1870
|
+
sawNonZeroLayoutRef.current = true;
|
|
1871
|
+
setLayoutBootKey((k) => k + 1);
|
|
1872
|
+
}
|
|
1873
|
+
};
|
|
1874
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_liquid_glass.LiquidGlassView, { ...props, onLayout, children }, `liquid-glass-${token}-${layoutBootKey}`);
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
// src/components/studio-sheet/StudioSheetBackground.tsx
|
|
1878
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1727
1879
|
function StudioSheetBackground({
|
|
1728
1880
|
style,
|
|
1729
1881
|
renderBackground
|
|
1730
1882
|
}) {
|
|
1731
1883
|
const theme = useTheme();
|
|
1732
|
-
const radius =
|
|
1884
|
+
const radius = import_react_native8.Platform.OS === "ios" ? 39 : 16;
|
|
1733
1885
|
const fallbackBgColor = theme.scheme === "dark" ? "rgba(11, 8, 15, 0.85)" : "rgba(255, 255, 255, 0.85)";
|
|
1734
1886
|
const secondaryBgBaseColor = theme.scheme === "dark" ? "rgb(24, 24, 27)" : "rgb(173, 173, 173)";
|
|
1735
1887
|
const containerStyle = {
|
|
@@ -1739,18 +1891,18 @@ function StudioSheetBackground({
|
|
|
1739
1891
|
overflow: "hidden"
|
|
1740
1892
|
};
|
|
1741
1893
|
if (renderBackground) {
|
|
1742
|
-
return /* @__PURE__ */ (0,
|
|
1894
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: renderBackground({ style: containerStyle }) });
|
|
1743
1895
|
}
|
|
1744
|
-
return /* @__PURE__ */ (0,
|
|
1745
|
-
/* @__PURE__ */ (0,
|
|
1746
|
-
|
|
1896
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
1897
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1898
|
+
ResettableLiquidGlassView,
|
|
1747
1899
|
{
|
|
1748
|
-
style: [containerStyle, !
|
|
1900
|
+
style: [containerStyle, !import_liquid_glass2.isLiquidGlassSupported && { backgroundColor: fallbackBgColor }],
|
|
1749
1901
|
effect: "regular"
|
|
1750
1902
|
}
|
|
1751
1903
|
),
|
|
1752
|
-
|
|
1753
|
-
|
|
1904
|
+
import_liquid_glass2.isLiquidGlassSupported && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1905
|
+
import_react_native8.View,
|
|
1754
1906
|
{
|
|
1755
1907
|
style: [
|
|
1756
1908
|
containerStyle,
|
|
@@ -1771,11 +1923,11 @@ function StudioSheetBackground({
|
|
|
1771
1923
|
}
|
|
1772
1924
|
|
|
1773
1925
|
// src/components/studio-sheet/StudioBottomSheet.tsx
|
|
1774
|
-
var
|
|
1926
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1775
1927
|
function StudioBottomSheet({
|
|
1776
1928
|
open,
|
|
1777
1929
|
onOpenChange,
|
|
1778
|
-
snapPoints = ["
|
|
1930
|
+
snapPoints = ["100%"],
|
|
1779
1931
|
sheetRef,
|
|
1780
1932
|
background,
|
|
1781
1933
|
children,
|
|
@@ -1783,16 +1935,16 @@ function StudioBottomSheet({
|
|
|
1783
1935
|
}) {
|
|
1784
1936
|
const theme = useTheme();
|
|
1785
1937
|
const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
|
|
1786
|
-
const internalSheetRef =
|
|
1938
|
+
const internalSheetRef = React11.useRef(null);
|
|
1787
1939
|
const resolvedSheetRef = sheetRef ?? internalSheetRef;
|
|
1788
|
-
const currentIndexRef =
|
|
1789
|
-
const lastAppStateRef =
|
|
1790
|
-
|
|
1791
|
-
const sub =
|
|
1940
|
+
const currentIndexRef = React11.useRef(open ? snapPoints.length - 1 : -1);
|
|
1941
|
+
const lastAppStateRef = React11.useRef(import_react_native9.AppState.currentState);
|
|
1942
|
+
React11.useEffect(() => {
|
|
1943
|
+
const sub = import_react_native9.AppState.addEventListener("change", (state) => {
|
|
1792
1944
|
const prev = lastAppStateRef.current;
|
|
1793
1945
|
lastAppStateRef.current = state;
|
|
1794
1946
|
if (state === "background" || state === "inactive") {
|
|
1795
|
-
|
|
1947
|
+
import_react_native9.Keyboard.dismiss();
|
|
1796
1948
|
return;
|
|
1797
1949
|
}
|
|
1798
1950
|
if (state !== "active") return;
|
|
@@ -1800,14 +1952,14 @@ function StudioBottomSheet({
|
|
|
1800
1952
|
if (!sheet) return;
|
|
1801
1953
|
const idx = currentIndexRef.current;
|
|
1802
1954
|
if (open && idx >= 0) {
|
|
1803
|
-
|
|
1955
|
+
import_react_native9.Keyboard.dismiss();
|
|
1804
1956
|
requestAnimationFrame(() => sheet.snapToIndex(idx));
|
|
1805
1957
|
setTimeout(() => sheet.snapToIndex(idx), 120);
|
|
1806
1958
|
}
|
|
1807
1959
|
});
|
|
1808
1960
|
return () => sub.remove();
|
|
1809
1961
|
}, [open, resolvedSheetRef]);
|
|
1810
|
-
|
|
1962
|
+
React11.useEffect(() => {
|
|
1811
1963
|
const sheet = resolvedSheetRef.current;
|
|
1812
1964
|
if (!sheet) return;
|
|
1813
1965
|
if (open) {
|
|
@@ -1816,42 +1968,42 @@ function StudioBottomSheet({
|
|
|
1816
1968
|
sheet.close();
|
|
1817
1969
|
}
|
|
1818
1970
|
}, [open, resolvedSheetRef, snapPoints.length]);
|
|
1819
|
-
const handleChange =
|
|
1971
|
+
const handleChange = React11.useCallback(
|
|
1820
1972
|
(index) => {
|
|
1821
1973
|
currentIndexRef.current = index;
|
|
1822
1974
|
onOpenChange == null ? void 0 : onOpenChange(index >= 0);
|
|
1823
1975
|
},
|
|
1824
1976
|
[onOpenChange]
|
|
1825
1977
|
);
|
|
1826
|
-
return /* @__PURE__ */ (0,
|
|
1978
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1827
1979
|
import_bottom_sheet.default,
|
|
1828
1980
|
{
|
|
1829
1981
|
ref: resolvedSheetRef,
|
|
1830
1982
|
index: open ? snapPoints.length - 1 : -1,
|
|
1831
1983
|
snapPoints,
|
|
1984
|
+
enableDynamicSizing: false,
|
|
1832
1985
|
enablePanDownToClose: true,
|
|
1833
|
-
|
|
1834
|
-
keyboardBlurBehavior: "restore",
|
|
1986
|
+
enableContentPanningGesture: false,
|
|
1835
1987
|
android_keyboardInputMode: "adjustResize",
|
|
1836
|
-
backgroundComponent: (props) => /* @__PURE__ */ (0,
|
|
1988
|
+
backgroundComponent: (props) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StudioSheetBackground, { ...props, renderBackground: background == null ? void 0 : background.renderBackground }),
|
|
1837
1989
|
topInset: insets.top,
|
|
1838
1990
|
bottomInset: 0,
|
|
1839
1991
|
handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
|
|
1840
1992
|
onChange: handleChange,
|
|
1841
1993
|
...bottomSheetProps,
|
|
1842
|
-
children: /* @__PURE__ */ (0,
|
|
1994
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.View, { style: { flex: 1, overflow: "hidden" }, children })
|
|
1843
1995
|
}
|
|
1844
1996
|
);
|
|
1845
1997
|
}
|
|
1846
1998
|
|
|
1847
1999
|
// src/components/studio-sheet/StudioSheetPager.tsx
|
|
1848
|
-
var
|
|
1849
|
-
var
|
|
1850
|
-
var
|
|
2000
|
+
var React12 = __toESM(require("react"));
|
|
2001
|
+
var import_react_native10 = require("react-native");
|
|
2002
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1851
2003
|
function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
1852
|
-
const anim =
|
|
1853
|
-
|
|
1854
|
-
|
|
2004
|
+
const anim = React12.useRef(new import_react_native10.Animated.Value(activePage === "chat" ? 1 : 0)).current;
|
|
2005
|
+
React12.useEffect(() => {
|
|
2006
|
+
import_react_native10.Animated.spring(anim, {
|
|
1855
2007
|
toValue: activePage === "chat" ? 1 : 0,
|
|
1856
2008
|
useNativeDriver: true,
|
|
1857
2009
|
tension: 65,
|
|
@@ -1860,9 +2012,9 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1860
2012
|
}, [activePage, anim]);
|
|
1861
2013
|
const previewTranslateX = anim.interpolate({ inputRange: [0, 1], outputRange: [0, -width] });
|
|
1862
2014
|
const chatTranslateX = anim.interpolate({ inputRange: [0, 1], outputRange: [width, 0] });
|
|
1863
|
-
return /* @__PURE__ */ (0,
|
|
1864
|
-
/* @__PURE__ */ (0,
|
|
1865
|
-
|
|
2015
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native10.Animated.View, { style: [{ flex: 1 }, style], children: [
|
|
2016
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2017
|
+
import_react_native10.Animated.View,
|
|
1866
2018
|
{
|
|
1867
2019
|
style: [
|
|
1868
2020
|
{
|
|
@@ -1878,8 +2030,8 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1878
2030
|
children: preview
|
|
1879
2031
|
}
|
|
1880
2032
|
),
|
|
1881
|
-
/* @__PURE__ */ (0,
|
|
1882
|
-
|
|
2033
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2034
|
+
import_react_native10.Animated.View,
|
|
1883
2035
|
{
|
|
1884
2036
|
style: [
|
|
1885
2037
|
{
|
|
@@ -1900,10 +2052,10 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1900
2052
|
|
|
1901
2053
|
// src/components/floating-draggable-button/FloatingDraggableButton.tsx
|
|
1902
2054
|
var import_react = require("react");
|
|
1903
|
-
var
|
|
2055
|
+
var import_react_native11 = require("react-native");
|
|
1904
2056
|
var Haptics = __toESM(require("expo-haptics"));
|
|
1905
2057
|
var import_react_native_reanimated = __toESM(require("react-native-reanimated"));
|
|
1906
|
-
var
|
|
2058
|
+
var import_liquid_glass3 = require("@callstack/liquid-glass");
|
|
1907
2059
|
|
|
1908
2060
|
// src/components/floating-draggable-button/constants.ts
|
|
1909
2061
|
var DEFAULT_SIZE = 48;
|
|
@@ -1914,11 +2066,10 @@ var DEFAULT_OFFSET = {
|
|
|
1914
2066
|
};
|
|
1915
2067
|
var ENTER_SCALE_FROM = 0.3;
|
|
1916
2068
|
var ENTER_ROTATION_FROM_DEG = -180;
|
|
1917
|
-
var HIDDEN_OPACITY = 0.3;
|
|
1918
2069
|
var PULSE_DURATION_MS = 900;
|
|
1919
2070
|
|
|
1920
2071
|
// src/components/floating-draggable-button/FloatingDraggableButton.tsx
|
|
1921
|
-
var
|
|
2072
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1922
2073
|
var HIDDEN_OFFSET_X = 20;
|
|
1923
2074
|
var SPRING_POSITION = { damping: 12, stiffness: 100, mass: 0.8 };
|
|
1924
2075
|
var SPRING_SCALE_IN = { damping: 10, stiffness: 200 };
|
|
@@ -1926,8 +2077,6 @@ var SPRING_SCALE_OUT = { damping: 12, stiffness: 150 };
|
|
|
1926
2077
|
var SPRING_ROTATION_IN = { damping: 15, stiffness: 80 };
|
|
1927
2078
|
var SPRING_ROTATION_GRAB = { damping: 20 };
|
|
1928
2079
|
var SPRING_SCALE_GRAB = { damping: 15, stiffness: 200 };
|
|
1929
|
-
var TIMING_OPACITY_IN = { duration: 300, easing: import_react_native_reanimated.Easing.out(import_react_native_reanimated.Easing.ease) };
|
|
1930
|
-
var TIMING_OPACITY_OUT = { duration: 250, easing: import_react_native_reanimated.Easing.in(import_react_native_reanimated.Easing.ease) };
|
|
1931
2080
|
function clamp(value, min, max) {
|
|
1932
2081
|
"worklet";
|
|
1933
2082
|
return Math.max(min, Math.min(max, value));
|
|
@@ -1959,7 +2108,7 @@ function FloatingDraggableButton({
|
|
|
1959
2108
|
backgroundColor
|
|
1960
2109
|
}) {
|
|
1961
2110
|
const theme = useTheme();
|
|
1962
|
-
const { width, height } = (0,
|
|
2111
|
+
const { width, height } = (0, import_react_native11.useWindowDimensions)();
|
|
1963
2112
|
const isDanger = variant === "danger";
|
|
1964
2113
|
const onPressRef = (0, import_react.useRef)(onPress);
|
|
1965
2114
|
(0, import_react.useEffect)(() => {
|
|
@@ -1974,30 +2123,20 @@ function FloatingDraggableButton({
|
|
|
1974
2123
|
const translateY = (0, import_react_native_reanimated.useSharedValue)(getHiddenTranslateY(height));
|
|
1975
2124
|
const scale = (0, import_react_native_reanimated.useSharedValue)(ENTER_SCALE_FROM);
|
|
1976
2125
|
const rotation = (0, import_react_native_reanimated.useSharedValue)(ENTER_ROTATION_FROM_DEG);
|
|
1977
|
-
const opacity = (0, import_react_native_reanimated.useSharedValue)(1);
|
|
1978
2126
|
const borderPulse = (0, import_react_native_reanimated.useSharedValue)(0);
|
|
1979
2127
|
const startPos = (0, import_react.useRef)({ x: 0, y: 0 });
|
|
1980
2128
|
const isAnimatingOut = (0, import_react.useRef)(false);
|
|
1981
2129
|
const animateToHidden = (0, import_react.useCallback)(
|
|
1982
2130
|
(options) => {
|
|
1983
|
-
|
|
2131
|
+
const finish = options == null ? void 0 : options.onFinish;
|
|
2132
|
+
translateX.value = (0, import_react_native_reanimated.withSpring)(getHiddenTranslateX(size), SPRING_POSITION, (finished) => {
|
|
2133
|
+
if (finished && finish) (0, import_react_native_reanimated.runOnJS)(finish)();
|
|
2134
|
+
});
|
|
1984
2135
|
translateY.value = (0, import_react_native_reanimated.withSpring)(getHiddenTranslateY(height), SPRING_POSITION);
|
|
1985
2136
|
scale.value = (0, import_react_native_reanimated.withSpring)(ENTER_SCALE_FROM, SPRING_SCALE_IN);
|
|
1986
2137
|
rotation.value = (0, import_react_native_reanimated.withSpring)(ENTER_ROTATION_FROM_DEG, SPRING_ROTATION_IN);
|
|
1987
|
-
const finish = options == null ? void 0 : options.onFinish;
|
|
1988
|
-
if (!finish) {
|
|
1989
|
-
opacity.value = (0, import_react_native_reanimated.withTiming)(HIDDEN_OPACITY, TIMING_OPACITY_OUT);
|
|
1990
|
-
return;
|
|
1991
|
-
}
|
|
1992
|
-
opacity.value = (0, import_react_native_reanimated.withTiming)(
|
|
1993
|
-
HIDDEN_OPACITY,
|
|
1994
|
-
TIMING_OPACITY_OUT,
|
|
1995
|
-
(finished) => {
|
|
1996
|
-
if (finished) (0, import_react_native_reanimated.runOnJS)(finish)();
|
|
1997
|
-
}
|
|
1998
|
-
);
|
|
1999
2138
|
},
|
|
2000
|
-
[height,
|
|
2139
|
+
[height, rotation, scale, size, translateX, translateY]
|
|
2001
2140
|
);
|
|
2002
2141
|
const animateOut = (0, import_react.useCallback)(() => {
|
|
2003
2142
|
if (isAnimatingOut.current) return;
|
|
@@ -2037,8 +2176,7 @@ function FloatingDraggableButton({
|
|
|
2037
2176
|
(0, import_react_native_reanimated.withSpring)(1, SPRING_SCALE_OUT)
|
|
2038
2177
|
);
|
|
2039
2178
|
rotation.value = (0, import_react_native_reanimated.withSpring)(0, SPRING_ROTATION_IN);
|
|
2040
|
-
|
|
2041
|
-
}, [height, offset.bottom, offset.left, opacity, rotation, scale, size, translateX, translateY]);
|
|
2179
|
+
}, [height, offset.bottom, offset.left, rotation, scale, size, translateX, translateY]);
|
|
2042
2180
|
(0, import_react.useEffect)(() => {
|
|
2043
2181
|
const timer = setTimeout(() => {
|
|
2044
2182
|
if (visible) {
|
|
@@ -2062,7 +2200,7 @@ function FloatingDraggableButton({
|
|
|
2062
2200
|
}
|
|
2063
2201
|
}, [forceShowTrigger, visible, animateIn]);
|
|
2064
2202
|
const panResponder = (0, import_react.useRef)(
|
|
2065
|
-
|
|
2203
|
+
import_react_native11.PanResponder.create({
|
|
2066
2204
|
onStartShouldSetPanResponder: () => true,
|
|
2067
2205
|
onMoveShouldSetPanResponder: () => true,
|
|
2068
2206
|
onPanResponderGrant: () => {
|
|
@@ -2094,8 +2232,7 @@ function FloatingDraggableButton({
|
|
|
2094
2232
|
{ translateY: translateY.value },
|
|
2095
2233
|
{ scale: scale.value },
|
|
2096
2234
|
{ rotate: `${rotation.value}deg` }
|
|
2097
|
-
]
|
|
2098
|
-
opacity: opacity.value
|
|
2235
|
+
]
|
|
2099
2236
|
}));
|
|
2100
2237
|
const borderAnimatedStyle = (0, import_react_native_reanimated.useAnimatedStyle)(() => {
|
|
2101
2238
|
const borderColor = (0, import_react_native_reanimated.interpolateColor)(
|
|
@@ -2109,7 +2246,7 @@ function FloatingDraggableButton({
|
|
|
2109
2246
|
borderRadius: size / 2
|
|
2110
2247
|
};
|
|
2111
2248
|
});
|
|
2112
|
-
return /* @__PURE__ */ (0,
|
|
2249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2113
2250
|
import_react_native_reanimated.default.View,
|
|
2114
2251
|
{
|
|
2115
2252
|
...panResponder.panHandlers,
|
|
@@ -2118,31 +2255,31 @@ function FloatingDraggableButton({
|
|
|
2118
2255
|
accessibilityRole: "button",
|
|
2119
2256
|
accessibilityLabel: ariaLabel,
|
|
2120
2257
|
children: [
|
|
2121
|
-
/* @__PURE__ */ (0,
|
|
2122
|
-
|
|
2258
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_reanimated.default.View, { style: [{ width: size, height: size, borderRadius: size / 2 }, borderAnimatedStyle], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2259
|
+
ResettableLiquidGlassView,
|
|
2123
2260
|
{
|
|
2124
|
-
style: [{ flex: 1, borderRadius: size / 2 }, !
|
|
2261
|
+
style: [{ flex: 1, borderRadius: size / 2 }, !import_liquid_glass3.isLiquidGlassSupported && { backgroundColor: fallbackBgColor }],
|
|
2125
2262
|
interactive: true,
|
|
2126
2263
|
effect: "clear",
|
|
2127
|
-
children: /* @__PURE__ */ (0,
|
|
2128
|
-
|
|
2264
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2265
|
+
import_react_native11.Pressable,
|
|
2129
2266
|
{
|
|
2130
2267
|
onPress: () => {
|
|
2131
2268
|
if (!disabled) animateOut();
|
|
2132
2269
|
},
|
|
2133
2270
|
style: styles.buttonInner,
|
|
2134
2271
|
android_ripple: { color: "rgba(255, 255, 255, 0.3)", borderless: true },
|
|
2135
|
-
children: children ?? /* @__PURE__ */ (0,
|
|
2272
|
+
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native11.View, {})
|
|
2136
2273
|
}
|
|
2137
2274
|
)
|
|
2138
2275
|
}
|
|
2139
2276
|
) }),
|
|
2140
|
-
badgeCount > 0 && /* @__PURE__ */ (0,
|
|
2277
|
+
badgeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native11.View, { style: [styles.badge, { backgroundColor: theme.colors.danger }], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native11.Text, { style: [styles.badgeText, { color: theme.colors.onDanger }], children: badgeCount > 99 ? "99+" : badgeCount }) })
|
|
2141
2278
|
]
|
|
2142
2279
|
}
|
|
2143
2280
|
);
|
|
2144
2281
|
}
|
|
2145
|
-
var styles =
|
|
2282
|
+
var styles = import_react_native11.StyleSheet.create({
|
|
2146
2283
|
floatingButton: {
|
|
2147
2284
|
position: "absolute",
|
|
2148
2285
|
justifyContent: "center",
|
|
@@ -2178,8 +2315,8 @@ var styles = import_react_native9.StyleSheet.create({
|
|
|
2178
2315
|
});
|
|
2179
2316
|
|
|
2180
2317
|
// src/components/overlays/EdgeGlowFrame.tsx
|
|
2181
|
-
var
|
|
2182
|
-
var
|
|
2318
|
+
var React13 = __toESM(require("react"));
|
|
2319
|
+
var import_react_native12 = require("react-native");
|
|
2183
2320
|
var import_expo_linear_gradient = require("expo-linear-gradient");
|
|
2184
2321
|
|
|
2185
2322
|
// src/components/utils/color.ts
|
|
@@ -2198,7 +2335,7 @@ function withAlpha(color, alpha) {
|
|
|
2198
2335
|
}
|
|
2199
2336
|
|
|
2200
2337
|
// src/components/overlays/EdgeGlowFrame.tsx
|
|
2201
|
-
var
|
|
2338
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2202
2339
|
function baseColor(role, theme) {
|
|
2203
2340
|
switch (role) {
|
|
2204
2341
|
case "danger":
|
|
@@ -2221,9 +2358,9 @@ function EdgeGlowFrame({
|
|
|
2221
2358
|
}) {
|
|
2222
2359
|
const theme = useTheme();
|
|
2223
2360
|
const alpha = Math.max(0, Math.min(1, intensity));
|
|
2224
|
-
const anim =
|
|
2225
|
-
|
|
2226
|
-
|
|
2361
|
+
const anim = React13.useRef(new import_react_native12.Animated.Value(visible ? 1 : 0)).current;
|
|
2362
|
+
React13.useEffect(() => {
|
|
2363
|
+
import_react_native12.Animated.timing(anim, {
|
|
2227
2364
|
toValue: visible ? 1 : 0,
|
|
2228
2365
|
duration: 300,
|
|
2229
2366
|
useNativeDriver: true
|
|
@@ -2232,8 +2369,8 @@ function EdgeGlowFrame({
|
|
|
2232
2369
|
const c = baseColor(role, theme);
|
|
2233
2370
|
const strong = withAlpha(c, 0.6 * alpha);
|
|
2234
2371
|
const soft = withAlpha(c, 0.22 * alpha);
|
|
2235
|
-
return /* @__PURE__ */ (0,
|
|
2236
|
-
/* @__PURE__ */ (0,
|
|
2372
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native12.Animated.View, { pointerEvents: "none", style: [{ position: "absolute", inset: 0, opacity: anim }, style], children: [
|
|
2373
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: { position: "absolute", top: 0, left: 0, right: 0, height: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2237
2374
|
import_expo_linear_gradient.LinearGradient,
|
|
2238
2375
|
{
|
|
2239
2376
|
colors: [strong, soft, "transparent"],
|
|
@@ -2242,7 +2379,7 @@ function EdgeGlowFrame({
|
|
|
2242
2379
|
style: { width: "100%", height: "100%" }
|
|
2243
2380
|
}
|
|
2244
2381
|
) }),
|
|
2245
|
-
/* @__PURE__ */ (0,
|
|
2382
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: { position: "absolute", bottom: 0, left: 0, right: 0, height: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2246
2383
|
import_expo_linear_gradient.LinearGradient,
|
|
2247
2384
|
{
|
|
2248
2385
|
colors: ["transparent", soft, strong],
|
|
@@ -2251,7 +2388,7 @@ function EdgeGlowFrame({
|
|
|
2251
2388
|
style: { width: "100%", height: "100%" }
|
|
2252
2389
|
}
|
|
2253
2390
|
) }),
|
|
2254
|
-
/* @__PURE__ */ (0,
|
|
2391
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: { position: "absolute", top: 0, bottom: 0, left: 0, width: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2255
2392
|
import_expo_linear_gradient.LinearGradient,
|
|
2256
2393
|
{
|
|
2257
2394
|
colors: [strong, soft, "transparent"],
|
|
@@ -2260,7 +2397,7 @@ function EdgeGlowFrame({
|
|
|
2260
2397
|
style: { width: "100%", height: "100%" }
|
|
2261
2398
|
}
|
|
2262
2399
|
) }),
|
|
2263
|
-
/* @__PURE__ */ (0,
|
|
2400
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: { position: "absolute", top: 0, bottom: 0, right: 0, width: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2264
2401
|
import_expo_linear_gradient.LinearGradient,
|
|
2265
2402
|
{
|
|
2266
2403
|
colors: ["transparent", soft, strong],
|
|
@@ -2273,13 +2410,13 @@ function EdgeGlowFrame({
|
|
|
2273
2410
|
}
|
|
2274
2411
|
|
|
2275
2412
|
// src/components/draw/DrawModeOverlay.tsx
|
|
2276
|
-
var
|
|
2277
|
-
var
|
|
2413
|
+
var React16 = __toESM(require("react"));
|
|
2414
|
+
var import_react_native16 = require("react-native");
|
|
2278
2415
|
var import_react_native_view_shot = require("react-native-view-shot");
|
|
2279
2416
|
|
|
2280
2417
|
// src/components/draw/DrawSurface.tsx
|
|
2281
|
-
var
|
|
2282
|
-
var
|
|
2418
|
+
var React14 = __toESM(require("react"));
|
|
2419
|
+
var import_react_native13 = require("react-native");
|
|
2283
2420
|
var import_react_native_svg = __toESM(require("react-native-svg"));
|
|
2284
2421
|
|
|
2285
2422
|
// src/components/draw/strokes.ts
|
|
@@ -2301,7 +2438,7 @@ function pointsToSmoothPath(points) {
|
|
|
2301
2438
|
}
|
|
2302
2439
|
|
|
2303
2440
|
// src/components/draw/DrawSurface.tsx
|
|
2304
|
-
var
|
|
2441
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2305
2442
|
function DrawSurface({
|
|
2306
2443
|
color,
|
|
2307
2444
|
strokeWidth,
|
|
@@ -2310,25 +2447,25 @@ function DrawSurface({
|
|
|
2310
2447
|
style,
|
|
2311
2448
|
minDistance = 1
|
|
2312
2449
|
}) {
|
|
2313
|
-
const [renderTick, setRenderTick] =
|
|
2314
|
-
const currentPointsRef =
|
|
2315
|
-
const rafRef =
|
|
2316
|
-
const triggerRender =
|
|
2450
|
+
const [renderTick, setRenderTick] = React14.useState(0);
|
|
2451
|
+
const currentPointsRef = React14.useRef([]);
|
|
2452
|
+
const rafRef = React14.useRef(null);
|
|
2453
|
+
const triggerRender = React14.useCallback(() => {
|
|
2317
2454
|
if (rafRef.current !== null) return;
|
|
2318
2455
|
rafRef.current = requestAnimationFrame(() => {
|
|
2319
2456
|
rafRef.current = null;
|
|
2320
2457
|
setRenderTick((n) => n + 1);
|
|
2321
2458
|
});
|
|
2322
2459
|
}, []);
|
|
2323
|
-
|
|
2460
|
+
React14.useEffect(() => () => {
|
|
2324
2461
|
if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);
|
|
2325
2462
|
}, []);
|
|
2326
|
-
const onStart =
|
|
2463
|
+
const onStart = React14.useCallback((e) => {
|
|
2327
2464
|
const { locationX, locationY } = e.nativeEvent;
|
|
2328
2465
|
currentPointsRef.current = [{ x: locationX, y: locationY }];
|
|
2329
2466
|
triggerRender();
|
|
2330
2467
|
}, [triggerRender]);
|
|
2331
|
-
const onMove =
|
|
2468
|
+
const onMove = React14.useCallback((e, _g) => {
|
|
2332
2469
|
const { locationX, locationY } = e.nativeEvent;
|
|
2333
2470
|
const pts = currentPointsRef.current;
|
|
2334
2471
|
if (pts.length > 0) {
|
|
@@ -2341,7 +2478,7 @@ function DrawSurface({
|
|
|
2341
2478
|
currentPointsRef.current = [...pts, { x: locationX, y: locationY }];
|
|
2342
2479
|
triggerRender();
|
|
2343
2480
|
}, [minDistance, triggerRender]);
|
|
2344
|
-
const onEnd =
|
|
2481
|
+
const onEnd = React14.useCallback(() => {
|
|
2345
2482
|
const points = currentPointsRef.current;
|
|
2346
2483
|
if (points.length > 0) {
|
|
2347
2484
|
onAddStroke({ points, color, width: strokeWidth });
|
|
@@ -2349,8 +2486,8 @@ function DrawSurface({
|
|
|
2349
2486
|
currentPointsRef.current = [];
|
|
2350
2487
|
triggerRender();
|
|
2351
2488
|
}, [color, onAddStroke, strokeWidth, triggerRender]);
|
|
2352
|
-
const panResponder =
|
|
2353
|
-
() =>
|
|
2489
|
+
const panResponder = React14.useMemo(
|
|
2490
|
+
() => import_react_native13.PanResponder.create({
|
|
2354
2491
|
onStartShouldSetPanResponder: () => true,
|
|
2355
2492
|
onMoveShouldSetPanResponder: () => true,
|
|
2356
2493
|
onPanResponderGrant: onStart,
|
|
@@ -2362,11 +2499,11 @@ function DrawSurface({
|
|
|
2362
2499
|
);
|
|
2363
2500
|
const currentPath = pointsToSmoothPath(currentPointsRef.current);
|
|
2364
2501
|
void renderTick;
|
|
2365
|
-
return /* @__PURE__ */ (0,
|
|
2502
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native13.View, { style: [import_react_native13.StyleSheet.absoluteFill, styles2.container, style], ...panResponder.panHandlers, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native_svg.default, { style: import_react_native13.StyleSheet.absoluteFill, width: "100%", height: "100%", children: [
|
|
2366
2503
|
strokes.map((s, idx) => {
|
|
2367
2504
|
const d = pointsToSmoothPath(s.points);
|
|
2368
2505
|
if (!d) return null;
|
|
2369
|
-
return /* @__PURE__ */ (0,
|
|
2506
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2370
2507
|
import_react_native_svg.Path,
|
|
2371
2508
|
{
|
|
2372
2509
|
d,
|
|
@@ -2379,7 +2516,7 @@ function DrawSurface({
|
|
|
2379
2516
|
idx
|
|
2380
2517
|
);
|
|
2381
2518
|
}),
|
|
2382
|
-
currentPath ? /* @__PURE__ */ (0,
|
|
2519
|
+
currentPath ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2383
2520
|
import_react_native_svg.Path,
|
|
2384
2521
|
{
|
|
2385
2522
|
d: currentPath,
|
|
@@ -2392,15 +2529,15 @@ function DrawSurface({
|
|
|
2392
2529
|
) : null
|
|
2393
2530
|
] }) });
|
|
2394
2531
|
}
|
|
2395
|
-
var styles2 =
|
|
2532
|
+
var styles2 = import_react_native13.StyleSheet.create({
|
|
2396
2533
|
container: {
|
|
2397
2534
|
zIndex: 5
|
|
2398
2535
|
}
|
|
2399
2536
|
});
|
|
2400
2537
|
|
|
2401
2538
|
// src/components/draw/DrawToolbar.tsx
|
|
2402
|
-
var
|
|
2403
|
-
var
|
|
2539
|
+
var React15 = __toESM(require("react"));
|
|
2540
|
+
var import_react_native15 = require("react-native");
|
|
2404
2541
|
var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
|
|
2405
2542
|
var import_lucide_react_native = require("lucide-react-native");
|
|
2406
2543
|
|
|
@@ -2419,8 +2556,8 @@ async function impact(style) {
|
|
|
2419
2556
|
}
|
|
2420
2557
|
|
|
2421
2558
|
// src/components/draw/DrawColorPicker.tsx
|
|
2422
|
-
var
|
|
2423
|
-
var
|
|
2559
|
+
var import_react_native14 = require("react-native");
|
|
2560
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2424
2561
|
function DrawColorPicker({
|
|
2425
2562
|
colors,
|
|
2426
2563
|
selected,
|
|
@@ -2454,10 +2591,10 @@ function DrawColorPicker({
|
|
|
2454
2591
|
return { ...base, ...selectedStyle, ...whiteStyle };
|
|
2455
2592
|
};
|
|
2456
2593
|
if (!expanded) {
|
|
2457
|
-
return /* @__PURE__ */ (0,
|
|
2594
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native14.Pressable, { onPress: onToggle, style: [swatchStyle(selected, true), style] });
|
|
2458
2595
|
}
|
|
2459
|
-
return /* @__PURE__ */ (0,
|
|
2460
|
-
|
|
2596
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native14.View, { style: [{ flexDirection: "row", alignItems: "center", gap: 8 }, style], children: colors.map((c, idx) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2597
|
+
import_react_native14.Pressable,
|
|
2461
2598
|
{
|
|
2462
2599
|
onPress: () => {
|
|
2463
2600
|
onSelect(c);
|
|
@@ -2470,7 +2607,7 @@ function DrawColorPicker({
|
|
|
2470
2607
|
}
|
|
2471
2608
|
|
|
2472
2609
|
// src/components/draw/DrawToolbar.tsx
|
|
2473
|
-
var
|
|
2610
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2474
2611
|
function DrawToolbar({
|
|
2475
2612
|
colors,
|
|
2476
2613
|
selectedColor,
|
|
@@ -2488,14 +2625,14 @@ function DrawToolbar({
|
|
|
2488
2625
|
style
|
|
2489
2626
|
}) {
|
|
2490
2627
|
const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
|
|
2491
|
-
const { width: screenWidth, height: screenHeight } = (0,
|
|
2492
|
-
const [expanded, setExpanded] =
|
|
2493
|
-
const pos =
|
|
2494
|
-
const start =
|
|
2495
|
-
const currentPos =
|
|
2496
|
-
|
|
2628
|
+
const { width: screenWidth, height: screenHeight } = (0, import_react_native15.useWindowDimensions)();
|
|
2629
|
+
const [expanded, setExpanded] = React15.useState(false);
|
|
2630
|
+
const pos = React15.useRef(new import_react_native15.Animated.ValueXY({ x: screenWidth / 2 - 110, y: -140 })).current;
|
|
2631
|
+
const start = React15.useRef({ x: 0, y: 0 });
|
|
2632
|
+
const currentPos = React15.useRef({ x: 0, y: 0 });
|
|
2633
|
+
React15.useEffect(() => {
|
|
2497
2634
|
if (hidden) return;
|
|
2498
|
-
|
|
2635
|
+
import_react_native15.Animated.spring(pos.y, {
|
|
2499
2636
|
toValue: insets.top + 60,
|
|
2500
2637
|
useNativeDriver: true,
|
|
2501
2638
|
damping: 12,
|
|
@@ -2503,7 +2640,7 @@ function DrawToolbar({
|
|
|
2503
2640
|
mass: 0.8
|
|
2504
2641
|
}).start();
|
|
2505
2642
|
}, [hidden, insets.top, pos.y]);
|
|
2506
|
-
|
|
2643
|
+
React15.useEffect(() => {
|
|
2507
2644
|
const id = pos.addListener((v) => {
|
|
2508
2645
|
currentPos.current = { x: v.x ?? 0, y: v.y ?? 0 };
|
|
2509
2646
|
});
|
|
@@ -2511,7 +2648,7 @@ function DrawToolbar({
|
|
|
2511
2648
|
pos.removeListener(id);
|
|
2512
2649
|
};
|
|
2513
2650
|
}, [pos]);
|
|
2514
|
-
const clamp2 =
|
|
2651
|
+
const clamp2 = React15.useCallback(
|
|
2515
2652
|
(x, y) => {
|
|
2516
2653
|
const minX = 10;
|
|
2517
2654
|
const maxX = Math.max(10, screenWidth - 230);
|
|
@@ -2521,8 +2658,8 @@ function DrawToolbar({
|
|
|
2521
2658
|
},
|
|
2522
2659
|
[insets.top, screenHeight, screenWidth]
|
|
2523
2660
|
);
|
|
2524
|
-
const panResponder =
|
|
2525
|
-
() =>
|
|
2661
|
+
const panResponder = React15.useMemo(
|
|
2662
|
+
() => import_react_native15.PanResponder.create({
|
|
2526
2663
|
onStartShouldSetPanResponder: () => false,
|
|
2527
2664
|
onMoveShouldSetPanResponder: (_e, g) => Math.abs(g.dx) > 5 || Math.abs(g.dy) > 5,
|
|
2528
2665
|
onPanResponderGrant: () => {
|
|
@@ -2534,7 +2671,7 @@ function DrawToolbar({
|
|
|
2534
2671
|
},
|
|
2535
2672
|
onPanResponderRelease: () => {
|
|
2536
2673
|
const next = clamp2(currentPos.current.x, currentPos.current.y);
|
|
2537
|
-
|
|
2674
|
+
import_react_native15.Animated.spring(pos, { toValue: next, useNativeDriver: true }).start();
|
|
2538
2675
|
}
|
|
2539
2676
|
}),
|
|
2540
2677
|
[clamp2, pos]
|
|
@@ -2549,9 +2686,9 @@ function DrawToolbar({
|
|
|
2549
2686
|
children
|
|
2550
2687
|
}) {
|
|
2551
2688
|
const isDisabled = Boolean(disabled) || Boolean(capturingDisabled);
|
|
2552
|
-
const [pressed, setPressed] =
|
|
2553
|
-
return /* @__PURE__ */ (0,
|
|
2554
|
-
|
|
2689
|
+
const [pressed, setPressed] = React15.useState(false);
|
|
2690
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2691
|
+
import_react_native15.View,
|
|
2555
2692
|
{
|
|
2556
2693
|
style: {
|
|
2557
2694
|
width: 28,
|
|
@@ -2562,8 +2699,8 @@ function DrawToolbar({
|
|
|
2562
2699
|
backgroundColor,
|
|
2563
2700
|
opacity: isDisabled ? 0.5 : pressed ? 0.85 : 1
|
|
2564
2701
|
},
|
|
2565
|
-
children: /* @__PURE__ */ (0,
|
|
2566
|
-
|
|
2702
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2703
|
+
import_react_native15.Pressable,
|
|
2567
2704
|
{
|
|
2568
2705
|
accessibilityRole: "button",
|
|
2569
2706
|
accessibilityLabel,
|
|
@@ -2579,8 +2716,8 @@ function DrawToolbar({
|
|
|
2579
2716
|
}
|
|
2580
2717
|
);
|
|
2581
2718
|
}
|
|
2582
|
-
return /* @__PURE__ */ (0,
|
|
2583
|
-
|
|
2719
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2720
|
+
import_react_native15.Animated.View,
|
|
2584
2721
|
{
|
|
2585
2722
|
style: [
|
|
2586
2723
|
{
|
|
@@ -2596,8 +2733,8 @@ function DrawToolbar({
|
|
|
2596
2733
|
style
|
|
2597
2734
|
],
|
|
2598
2735
|
...panResponder.panHandlers,
|
|
2599
|
-
children: /* @__PURE__ */ (0,
|
|
2600
|
-
|
|
2736
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2737
|
+
import_react_native15.View,
|
|
2601
2738
|
{
|
|
2602
2739
|
style: {
|
|
2603
2740
|
backgroundColor: "#F43F5E",
|
|
@@ -2605,9 +2742,9 @@ function DrawToolbar({
|
|
|
2605
2742
|
padding: 12,
|
|
2606
2743
|
minWidth: 220
|
|
2607
2744
|
},
|
|
2608
|
-
children: /* @__PURE__ */ (0,
|
|
2609
|
-
renderDragHandle ? renderDragHandle() : /* @__PURE__ */ (0,
|
|
2610
|
-
/* @__PURE__ */ (0,
|
|
2745
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native15.View, { style: { flexDirection: "row", alignItems: "center", gap: 8 }, children: [
|
|
2746
|
+
renderDragHandle ? renderDragHandle() : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react_native.GripVertical, { size: 20, color: "rgba(255, 255, 255, 0.6)" }),
|
|
2747
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2611
2748
|
DrawColorPicker,
|
|
2612
2749
|
{
|
|
2613
2750
|
colors,
|
|
@@ -2623,8 +2760,8 @@ function DrawToolbar({
|
|
|
2623
2760
|
}
|
|
2624
2761
|
}
|
|
2625
2762
|
),
|
|
2626
|
-
/* @__PURE__ */ (0,
|
|
2627
|
-
/* @__PURE__ */ (0,
|
|
2763
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native15.View, { style: { width: 1, height: 20, backgroundColor: "rgba(255, 255, 255, 0.3)", marginHorizontal: 4 } }),
|
|
2764
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2628
2765
|
CircleActionButton,
|
|
2629
2766
|
{
|
|
2630
2767
|
accessibilityLabel: "Undo",
|
|
@@ -2635,10 +2772,10 @@ function DrawToolbar({
|
|
|
2635
2772
|
void impact("light");
|
|
2636
2773
|
onUndo();
|
|
2637
2774
|
},
|
|
2638
|
-
children: renderUndoIcon ? renderUndoIcon() : /* @__PURE__ */ (0,
|
|
2775
|
+
children: renderUndoIcon ? renderUndoIcon() : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react_native.Undo2, { size: 16, color: canUndo ? "#FFFFFF" : "rgba(255,255,255,0.4)" })
|
|
2639
2776
|
}
|
|
2640
2777
|
),
|
|
2641
|
-
/* @__PURE__ */ (0,
|
|
2778
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2642
2779
|
CircleActionButton,
|
|
2643
2780
|
{
|
|
2644
2781
|
accessibilityLabel: "Cancel",
|
|
@@ -2648,10 +2785,10 @@ function DrawToolbar({
|
|
|
2648
2785
|
void impact("medium");
|
|
2649
2786
|
onCancel();
|
|
2650
2787
|
},
|
|
2651
|
-
children: renderCancelIcon ? renderCancelIcon() : /* @__PURE__ */ (0,
|
|
2788
|
+
children: renderCancelIcon ? renderCancelIcon() : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react_native.X, { size: 16, color: "#FFFFFF" })
|
|
2652
2789
|
}
|
|
2653
2790
|
),
|
|
2654
|
-
/* @__PURE__ */ (0,
|
|
2791
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2655
2792
|
CircleActionButton,
|
|
2656
2793
|
{
|
|
2657
2794
|
accessibilityLabel: "Done",
|
|
@@ -2661,7 +2798,7 @@ function DrawToolbar({
|
|
|
2661
2798
|
void impact("medium");
|
|
2662
2799
|
onDone();
|
|
2663
2800
|
},
|
|
2664
|
-
children: capturing ? /* @__PURE__ */ (0,
|
|
2801
|
+
children: capturing ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native15.ActivityIndicator, { color: "#FFFFFF", size: "small" }) : renderDoneIcon ? renderDoneIcon() : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react_native.Check, { size: 16, color: "#FFFFFF" })
|
|
2665
2802
|
}
|
|
2666
2803
|
)
|
|
2667
2804
|
] })
|
|
@@ -2672,7 +2809,7 @@ function DrawToolbar({
|
|
|
2672
2809
|
}
|
|
2673
2810
|
|
|
2674
2811
|
// src/components/draw/DrawModeOverlay.tsx
|
|
2675
|
-
var
|
|
2812
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2676
2813
|
function DrawModeOverlay({
|
|
2677
2814
|
visible,
|
|
2678
2815
|
captureTargetRef,
|
|
@@ -2687,7 +2824,7 @@ function DrawModeOverlay({
|
|
|
2687
2824
|
renderDragHandle
|
|
2688
2825
|
}) {
|
|
2689
2826
|
const theme = useTheme();
|
|
2690
|
-
const defaultPalette =
|
|
2827
|
+
const defaultPalette = React16.useMemo(
|
|
2691
2828
|
() => [
|
|
2692
2829
|
"#EF4444",
|
|
2693
2830
|
// Red
|
|
@@ -2705,11 +2842,11 @@ function DrawModeOverlay({
|
|
|
2705
2842
|
[]
|
|
2706
2843
|
);
|
|
2707
2844
|
const colors = palette && palette.length > 0 ? palette : defaultPalette;
|
|
2708
|
-
const [selectedColor, setSelectedColor] =
|
|
2709
|
-
const [strokes, setStrokes] =
|
|
2710
|
-
const [capturing, setCapturing] =
|
|
2711
|
-
const [hideUi, setHideUi] =
|
|
2712
|
-
|
|
2845
|
+
const [selectedColor, setSelectedColor] = React16.useState(colors[0] ?? "#EF4444");
|
|
2846
|
+
const [strokes, setStrokes] = React16.useState([]);
|
|
2847
|
+
const [capturing, setCapturing] = React16.useState(false);
|
|
2848
|
+
const [hideUi, setHideUi] = React16.useState(false);
|
|
2849
|
+
React16.useEffect(() => {
|
|
2713
2850
|
if (!visible) return;
|
|
2714
2851
|
setStrokes([]);
|
|
2715
2852
|
setSelectedColor(colors[0] ?? "#EF4444");
|
|
@@ -2717,14 +2854,14 @@ function DrawModeOverlay({
|
|
|
2717
2854
|
setHideUi(false);
|
|
2718
2855
|
}, [colors, visible]);
|
|
2719
2856
|
const canUndo = strokes.length > 0;
|
|
2720
|
-
const handleUndo =
|
|
2857
|
+
const handleUndo = React16.useCallback(() => {
|
|
2721
2858
|
setStrokes((prev) => prev.slice(0, -1));
|
|
2722
2859
|
}, []);
|
|
2723
|
-
const handleCancel =
|
|
2860
|
+
const handleCancel = React16.useCallback(() => {
|
|
2724
2861
|
setStrokes([]);
|
|
2725
2862
|
onCancel();
|
|
2726
2863
|
}, [onCancel]);
|
|
2727
|
-
const handleDone =
|
|
2864
|
+
const handleDone = React16.useCallback(async () => {
|
|
2728
2865
|
if (!captureTargetRef.current || capturing) return;
|
|
2729
2866
|
try {
|
|
2730
2867
|
setCapturing(true);
|
|
@@ -2746,9 +2883,9 @@ function DrawModeOverlay({
|
|
|
2746
2883
|
}
|
|
2747
2884
|
}, [captureTargetRef, capturing, onCapture]);
|
|
2748
2885
|
if (!visible) return null;
|
|
2749
|
-
return /* @__PURE__ */ (0,
|
|
2750
|
-
/* @__PURE__ */ (0,
|
|
2751
|
-
/* @__PURE__ */ (0,
|
|
2886
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native16.View, { style: [import_react_native16.StyleSheet.absoluteFill, styles3.root, style], pointerEvents: "box-none", children: [
|
|
2887
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(EdgeGlowFrame, { visible: !hideUi, role: "danger", thickness: 50, intensity: 1 }),
|
|
2888
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2752
2889
|
DrawSurface,
|
|
2753
2890
|
{
|
|
2754
2891
|
color: selectedColor,
|
|
@@ -2757,7 +2894,7 @@ function DrawModeOverlay({
|
|
|
2757
2894
|
onAddStroke: (stroke) => setStrokes((prev) => [...prev, stroke])
|
|
2758
2895
|
}
|
|
2759
2896
|
),
|
|
2760
|
-
/* @__PURE__ */ (0,
|
|
2897
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
2761
2898
|
DrawToolbar,
|
|
2762
2899
|
{
|
|
2763
2900
|
hidden: hideUi,
|
|
@@ -2777,32 +2914,32 @@ function DrawModeOverlay({
|
|
|
2777
2914
|
)
|
|
2778
2915
|
] });
|
|
2779
2916
|
}
|
|
2780
|
-
var styles3 =
|
|
2917
|
+
var styles3 = import_react_native16.StyleSheet.create({
|
|
2781
2918
|
root: {
|
|
2782
2919
|
zIndex: 9999
|
|
2783
2920
|
}
|
|
2784
2921
|
});
|
|
2785
2922
|
|
|
2786
2923
|
// src/components/comments/AppCommentsSheet.tsx
|
|
2787
|
-
var
|
|
2788
|
-
var
|
|
2924
|
+
var React23 = __toESM(require("react"));
|
|
2925
|
+
var import_react_native22 = require("react-native");
|
|
2789
2926
|
var import_bottom_sheet3 = require("@gorhom/bottom-sheet");
|
|
2790
2927
|
var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
|
|
2791
|
-
var
|
|
2928
|
+
var import_liquid_glass5 = require("@callstack/liquid-glass");
|
|
2792
2929
|
var import_lucide_react_native4 = require("lucide-react-native");
|
|
2793
2930
|
|
|
2794
2931
|
// src/components/chat/ChatComposer.tsx
|
|
2795
|
-
var
|
|
2796
|
-
var
|
|
2797
|
-
var
|
|
2932
|
+
var React18 = __toESM(require("react"));
|
|
2933
|
+
var import_react_native18 = require("react-native");
|
|
2934
|
+
var import_liquid_glass4 = require("@callstack/liquid-glass");
|
|
2798
2935
|
var import_lucide_react_native3 = require("lucide-react-native");
|
|
2799
2936
|
|
|
2800
2937
|
// src/components/chat/MultilineTextInput.tsx
|
|
2801
|
-
var
|
|
2802
|
-
var
|
|
2938
|
+
var React17 = __toESM(require("react"));
|
|
2939
|
+
var import_react_native17 = require("react-native");
|
|
2803
2940
|
var import_bottom_sheet2 = require("@gorhom/bottom-sheet");
|
|
2804
|
-
var
|
|
2805
|
-
var MultilineTextInput =
|
|
2941
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2942
|
+
var MultilineTextInput = React17.forwardRef(function MultilineTextInput2({ useBottomSheetTextInput = false, placeholder, placeholderTextColor, style, ...props }, ref) {
|
|
2806
2943
|
const theme = useTheme();
|
|
2807
2944
|
const baseStyle = {
|
|
2808
2945
|
minHeight: 44,
|
|
@@ -2822,12 +2959,12 @@ var MultilineTextInput = React15.forwardRef(function MultilineTextInput2({ useBo
|
|
|
2822
2959
|
style: [baseStyle, style],
|
|
2823
2960
|
textAlignVertical: "top"
|
|
2824
2961
|
};
|
|
2825
|
-
return useBottomSheetTextInput ? /* @__PURE__ */ (0,
|
|
2962
|
+
return useBottomSheetTextInput ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_bottom_sheet2.BottomSheetTextInput, { ref, ...commonProps }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native17.TextInput, { ref, ...commonProps });
|
|
2826
2963
|
});
|
|
2827
2964
|
|
|
2828
2965
|
// src/components/icons/StudioIcons.tsx
|
|
2829
2966
|
var import_lucide_react_native2 = require("lucide-react-native");
|
|
2830
|
-
var
|
|
2967
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2831
2968
|
function useResolvedIconColor(token) {
|
|
2832
2969
|
const theme = useTheme();
|
|
2833
2970
|
switch (token) {
|
|
@@ -2851,7 +2988,7 @@ function useResolvedIconColor(token) {
|
|
|
2851
2988
|
function makeIcon(Comp) {
|
|
2852
2989
|
return function StudioIcon({ size = 20, strokeWidth = 2, colorToken = "floatingContent", ...rest }) {
|
|
2853
2990
|
const color = useResolvedIconColor(colorToken);
|
|
2854
|
-
return /* @__PURE__ */ (0,
|
|
2991
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Comp, { size, strokeWidth, color, ...rest });
|
|
2855
2992
|
};
|
|
2856
2993
|
}
|
|
2857
2994
|
var IconHome = makeIcon(import_lucide_react_native2.Home);
|
|
@@ -2867,17 +3004,17 @@ var IconArrowDown = makeIcon(import_lucide_react_native2.ArrowDown);
|
|
|
2867
3004
|
var IconApprove = makeIcon(import_lucide_react_native2.Check);
|
|
2868
3005
|
|
|
2869
3006
|
// src/components/chat/ChatComposer.tsx
|
|
2870
|
-
var
|
|
3007
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2871
3008
|
var THUMBNAIL_HEIGHT = 90;
|
|
2872
3009
|
function AspectRatioThumbnail({
|
|
2873
3010
|
uri,
|
|
2874
3011
|
onRemove,
|
|
2875
3012
|
renderRemoveIcon
|
|
2876
3013
|
}) {
|
|
2877
|
-
const [aspectRatio, setAspectRatio] =
|
|
2878
|
-
return /* @__PURE__ */ (0,
|
|
2879
|
-
/* @__PURE__ */ (0,
|
|
2880
|
-
|
|
3014
|
+
const [aspectRatio, setAspectRatio] = React18.useState(1);
|
|
3015
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native18.View, { style: { height: THUMBNAIL_HEIGHT, aspectRatio, position: "relative" }, children: [
|
|
3016
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native18.View, { style: { flex: 1, borderRadius: 8, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3017
|
+
import_react_native18.Image,
|
|
2881
3018
|
{
|
|
2882
3019
|
source: { uri },
|
|
2883
3020
|
style: { width: "100%", height: "100%" },
|
|
@@ -2889,8 +3026,8 @@ function AspectRatioThumbnail({
|
|
|
2889
3026
|
}
|
|
2890
3027
|
}
|
|
2891
3028
|
) }),
|
|
2892
|
-
onRemove ? /* @__PURE__ */ (0,
|
|
2893
|
-
|
|
3029
|
+
onRemove ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3030
|
+
import_react_native18.Pressable,
|
|
2894
3031
|
{
|
|
2895
3032
|
style: {
|
|
2896
3033
|
position: "absolute",
|
|
@@ -2906,7 +3043,7 @@ function AspectRatioThumbnail({
|
|
|
2906
3043
|
},
|
|
2907
3044
|
onPress: onRemove,
|
|
2908
3045
|
hitSlop: 10,
|
|
2909
|
-
children: renderRemoveIcon ? renderRemoveIcon() : /* @__PURE__ */ (0,
|
|
3046
|
+
children: renderRemoveIcon ? renderRemoveIcon() : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconClose, { size: 12, colorToken: "onPrimary" })
|
|
2910
3047
|
}
|
|
2911
3048
|
) : null
|
|
2912
3049
|
] });
|
|
@@ -2931,19 +3068,19 @@ function ChatComposer({
|
|
|
2931
3068
|
style
|
|
2932
3069
|
}) {
|
|
2933
3070
|
const theme = useTheme();
|
|
2934
|
-
const [internal, setInternal] =
|
|
3071
|
+
const [internal, setInternal] = React18.useState("");
|
|
2935
3072
|
const text = value ?? internal;
|
|
2936
3073
|
const setText = onChangeValue ?? setInternal;
|
|
2937
3074
|
const hasAttachments = attachments.length > 0;
|
|
2938
3075
|
const hasText = text.trim().length > 0;
|
|
2939
3076
|
const composerMinHeight = hasAttachments ? THUMBNAIL_HEIGHT + 44 + 24 : 44;
|
|
2940
3077
|
const isButtonDisabled = sending || disabled || sendDisabled;
|
|
2941
|
-
const maxInputHeight =
|
|
2942
|
-
const shakeAnim =
|
|
2943
|
-
const [sendPressed, setSendPressed] =
|
|
2944
|
-
const inputRef =
|
|
2945
|
-
const prevAutoFocusRef =
|
|
2946
|
-
|
|
3078
|
+
const maxInputHeight = React18.useMemo(() => import_react_native18.Dimensions.get("window").height * 0.5, []);
|
|
3079
|
+
const shakeAnim = React18.useRef(new import_react_native18.Animated.Value(0)).current;
|
|
3080
|
+
const [sendPressed, setSendPressed] = React18.useState(false);
|
|
3081
|
+
const inputRef = React18.useRef(null);
|
|
3082
|
+
const prevAutoFocusRef = React18.useRef(false);
|
|
3083
|
+
React18.useEffect(() => {
|
|
2947
3084
|
const shouldFocus = autoFocus && !prevAutoFocusRef.current && !disabled && !sending;
|
|
2948
3085
|
prevAutoFocusRef.current = autoFocus;
|
|
2949
3086
|
if (!shouldFocus) return;
|
|
@@ -2953,17 +3090,17 @@ function ChatComposer({
|
|
|
2953
3090
|
}, 75);
|
|
2954
3091
|
return () => clearTimeout(t);
|
|
2955
3092
|
}, [autoFocus, disabled, sending]);
|
|
2956
|
-
const triggerShake =
|
|
3093
|
+
const triggerShake = React18.useCallback(() => {
|
|
2957
3094
|
shakeAnim.setValue(0);
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
3095
|
+
import_react_native18.Animated.sequence([
|
|
3096
|
+
import_react_native18.Animated.timing(shakeAnim, { toValue: 10, duration: 50, useNativeDriver: true }),
|
|
3097
|
+
import_react_native18.Animated.timing(shakeAnim, { toValue: -10, duration: 50, useNativeDriver: true }),
|
|
3098
|
+
import_react_native18.Animated.timing(shakeAnim, { toValue: 10, duration: 50, useNativeDriver: true }),
|
|
3099
|
+
import_react_native18.Animated.timing(shakeAnim, { toValue: -10, duration: 50, useNativeDriver: true }),
|
|
3100
|
+
import_react_native18.Animated.timing(shakeAnim, { toValue: 0, duration: 50, useNativeDriver: true })
|
|
2964
3101
|
]).start();
|
|
2965
3102
|
}, [shakeAnim]);
|
|
2966
|
-
const handleSend =
|
|
3103
|
+
const handleSend = React18.useCallback(async () => {
|
|
2967
3104
|
if (isButtonDisabled) return;
|
|
2968
3105
|
if (!hasText) {
|
|
2969
3106
|
triggerShake();
|
|
@@ -2975,33 +3112,34 @@ function ChatComposer({
|
|
|
2975
3112
|
}, [attachments, hasText, isButtonDisabled, onSend, setText, text, triggerShake]);
|
|
2976
3113
|
const textareaBgColor = theme.scheme === "dark" ? "#18181B" : "#F6F6F6";
|
|
2977
3114
|
const placeholderTextColor = theme.scheme === "dark" ? "#A1A1AA" : "#71717A";
|
|
2978
|
-
|
|
2979
|
-
|
|
3115
|
+
const sendBg = withAlpha(theme.colors.primary, isButtonDisabled ? 0.6 : sendPressed ? 0.9 : 1);
|
|
3116
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3117
|
+
import_react_native18.View,
|
|
2980
3118
|
{
|
|
2981
3119
|
style: [{ paddingHorizontal: 16, paddingBottom: 12, paddingTop: 8 }, style],
|
|
2982
3120
|
onLayout: (e) => onLayout == null ? void 0 : onLayout({ height: e.nativeEvent.layout.height }),
|
|
2983
|
-
children: /* @__PURE__ */ (0,
|
|
2984
|
-
/* @__PURE__ */ (0,
|
|
2985
|
-
|
|
3121
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native18.View, { style: { flexDirection: "row", alignItems: "flex-end", gap: 8 }, children: [
|
|
3122
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native18.Animated.View, { style: { flex: 1, transform: [{ translateX: shakeAnim }] }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
3123
|
+
ResettableLiquidGlassView,
|
|
2986
3124
|
{
|
|
2987
3125
|
style: [
|
|
2988
3126
|
// LiquidGlassView doesn't reliably auto-size to children; ensure enough height for the
|
|
2989
3127
|
// thumbnail strip when attachments are present.
|
|
2990
3128
|
{ borderRadius: 24, flex: 1, minHeight: composerMinHeight },
|
|
2991
|
-
!
|
|
3129
|
+
!import_liquid_glass4.isLiquidGlassSupported && { backgroundColor: textareaBgColor }
|
|
2992
3130
|
],
|
|
2993
3131
|
interactive: true,
|
|
2994
3132
|
effect: "clear",
|
|
2995
3133
|
children: [
|
|
2996
|
-
hasAttachments ? /* @__PURE__ */ (0,
|
|
2997
|
-
|
|
3134
|
+
hasAttachments ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
3135
|
+
import_react_native18.ScrollView,
|
|
2998
3136
|
{
|
|
2999
3137
|
horizontal: true,
|
|
3000
3138
|
showsHorizontalScrollIndicator: false,
|
|
3001
3139
|
keyboardShouldPersistTaps: "handled",
|
|
3002
3140
|
contentContainerStyle: { gap: 8, paddingHorizontal: 12, paddingTop: 12 },
|
|
3003
3141
|
children: [
|
|
3004
|
-
attachments.map((uri, index) => /* @__PURE__ */ (0,
|
|
3142
|
+
attachments.map((uri, index) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3005
3143
|
AspectRatioThumbnail,
|
|
3006
3144
|
{
|
|
3007
3145
|
uri,
|
|
@@ -3010,8 +3148,8 @@ function ChatComposer({
|
|
|
3010
3148
|
},
|
|
3011
3149
|
`attachment-${index}`
|
|
3012
3150
|
)),
|
|
3013
|
-
onAddAttachment ? renderAddAttachment ? renderAddAttachment() : /* @__PURE__ */ (0,
|
|
3014
|
-
|
|
3151
|
+
onAddAttachment ? renderAddAttachment ? renderAddAttachment() : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3152
|
+
import_react_native18.Pressable,
|
|
3015
3153
|
{
|
|
3016
3154
|
style: {
|
|
3017
3155
|
height: THUMBNAIL_HEIGHT,
|
|
@@ -3025,13 +3163,13 @@ function ChatComposer({
|
|
|
3025
3163
|
backgroundColor: "rgba(255, 255, 255, 0.05)"
|
|
3026
3164
|
},
|
|
3027
3165
|
onPress: onAddAttachment,
|
|
3028
|
-
children: /* @__PURE__ */ (0,
|
|
3166
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react_native3.Plus, { size: 24, color: "rgba(255, 255, 255, 0.5)" })
|
|
3029
3167
|
}
|
|
3030
3168
|
) : null
|
|
3031
3169
|
]
|
|
3032
3170
|
}
|
|
3033
3171
|
) : null,
|
|
3034
|
-
/* @__PURE__ */ (0,
|
|
3172
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3035
3173
|
MultilineTextInput,
|
|
3036
3174
|
{
|
|
3037
3175
|
ref: inputRef,
|
|
@@ -3056,25 +3194,24 @@ function ChatComposer({
|
|
|
3056
3194
|
]
|
|
3057
3195
|
}
|
|
3058
3196
|
) }),
|
|
3059
|
-
/* @__PURE__ */ (0,
|
|
3060
|
-
|
|
3197
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3198
|
+
ResettableLiquidGlassView,
|
|
3061
3199
|
{
|
|
3062
|
-
style: [{ borderRadius: 100 }, !
|
|
3200
|
+
style: [{ borderRadius: 100 }, !import_liquid_glass4.isLiquidGlassSupported && { backgroundColor: textareaBgColor }],
|
|
3063
3201
|
interactive: true,
|
|
3064
3202
|
effect: "clear",
|
|
3065
|
-
children: /* @__PURE__ */ (0,
|
|
3066
|
-
|
|
3203
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3204
|
+
import_react_native18.View,
|
|
3067
3205
|
{
|
|
3068
3206
|
style: {
|
|
3069
3207
|
width: 44,
|
|
3070
3208
|
height: 44,
|
|
3071
3209
|
borderRadius: 22,
|
|
3072
3210
|
overflow: "hidden",
|
|
3073
|
-
backgroundColor:
|
|
3074
|
-
opacity: isButtonDisabled ? 0.6 : sendPressed ? 0.9 : 1
|
|
3211
|
+
backgroundColor: sendBg
|
|
3075
3212
|
},
|
|
3076
|
-
children: /* @__PURE__ */ (0,
|
|
3077
|
-
|
|
3213
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3214
|
+
import_react_native18.Pressable,
|
|
3078
3215
|
{
|
|
3079
3216
|
accessibilityRole: "button",
|
|
3080
3217
|
accessibilityLabel: "Send",
|
|
@@ -3083,7 +3220,7 @@ function ChatComposer({
|
|
|
3083
3220
|
onPressIn: () => setSendPressed(true),
|
|
3084
3221
|
onPressOut: () => setSendPressed(false),
|
|
3085
3222
|
style: { flex: 1, alignItems: "center", justifyContent: "center" },
|
|
3086
|
-
children: sending ? /* @__PURE__ */ (0,
|
|
3223
|
+
children: sending ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native18.ActivityIndicator, {}) : renderSendIcon ? renderSendIcon() : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconChevronRight, { size: 20, colorToken: "onPrimary" })
|
|
3087
3224
|
}
|
|
3088
3225
|
)
|
|
3089
3226
|
}
|
|
@@ -3096,12 +3233,12 @@ function ChatComposer({
|
|
|
3096
3233
|
}
|
|
3097
3234
|
|
|
3098
3235
|
// src/components/comments/CommentRow.tsx
|
|
3099
|
-
var
|
|
3100
|
-
var
|
|
3236
|
+
var React19 = __toESM(require("react"));
|
|
3237
|
+
var import_react_native20 = require("react-native");
|
|
3101
3238
|
|
|
3102
3239
|
// src/components/primitives/Avatar.tsx
|
|
3103
|
-
var
|
|
3104
|
-
var
|
|
3240
|
+
var import_react_native19 = require("react-native");
|
|
3241
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3105
3242
|
function initialsFrom(name) {
|
|
3106
3243
|
var _a, _b;
|
|
3107
3244
|
const trimmed = (name ?? "").trim();
|
|
@@ -3119,8 +3256,8 @@ function Avatar({
|
|
|
3119
3256
|
const theme = useTheme();
|
|
3120
3257
|
const radius = size / 2;
|
|
3121
3258
|
const fallbackBg = fallbackBackgroundColor ?? theme.colors.neutral;
|
|
3122
|
-
return /* @__PURE__ */ (0,
|
|
3123
|
-
|
|
3259
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3260
|
+
import_react_native19.View,
|
|
3124
3261
|
{
|
|
3125
3262
|
style: [
|
|
3126
3263
|
{
|
|
@@ -3134,14 +3271,14 @@ function Avatar({
|
|
|
3134
3271
|
},
|
|
3135
3272
|
style
|
|
3136
3273
|
],
|
|
3137
|
-
children: uri ? /* @__PURE__ */ (0,
|
|
3138
|
-
|
|
3274
|
+
children: uri ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3275
|
+
import_react_native19.Image,
|
|
3139
3276
|
{
|
|
3140
3277
|
source: { uri },
|
|
3141
3278
|
style: [{ width: size, height: size }, imageStyle],
|
|
3142
3279
|
resizeMode: "cover"
|
|
3143
3280
|
}
|
|
3144
|
-
) : /* @__PURE__ */ (0,
|
|
3281
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { variant: "caption", style: { color: theme.colors.onNeutral }, children: initialsFrom(name) })
|
|
3145
3282
|
}
|
|
3146
3283
|
);
|
|
3147
3284
|
}
|
|
@@ -3165,12 +3302,12 @@ function formatTimeAgo(iso) {
|
|
|
3165
3302
|
}
|
|
3166
3303
|
|
|
3167
3304
|
// src/components/comments/CommentRow.tsx
|
|
3168
|
-
var
|
|
3305
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3169
3306
|
function CommentRow({ comment, showDivider }) {
|
|
3170
3307
|
const theme = useTheme();
|
|
3171
|
-
const [authorName, setAuthorName] =
|
|
3172
|
-
const [authorAvatar, setAuthorAvatar] =
|
|
3173
|
-
|
|
3308
|
+
const [authorName, setAuthorName] = React19.useState(null);
|
|
3309
|
+
const [authorAvatar, setAuthorAvatar] = React19.useState(null);
|
|
3310
|
+
React19.useEffect(() => {
|
|
3174
3311
|
let cancelled = false;
|
|
3175
3312
|
(async () => {
|
|
3176
3313
|
try {
|
|
@@ -3185,8 +3322,8 @@ function CommentRow({ comment, showDivider }) {
|
|
|
3185
3322
|
cancelled = true;
|
|
3186
3323
|
};
|
|
3187
3324
|
}, [comment.authorId]);
|
|
3188
|
-
return /* @__PURE__ */ (0,
|
|
3189
|
-
|
|
3325
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
3326
|
+
import_react_native20.View,
|
|
3190
3327
|
{
|
|
3191
3328
|
style: {
|
|
3192
3329
|
flexDirection: "row",
|
|
@@ -3196,13 +3333,13 @@ function CommentRow({ comment, showDivider }) {
|
|
|
3196
3333
|
borderBottomColor: withAlpha(theme.colors.border, 0.5)
|
|
3197
3334
|
},
|
|
3198
3335
|
children: [
|
|
3199
|
-
/* @__PURE__ */ (0,
|
|
3200
|
-
/* @__PURE__ */ (0,
|
|
3201
|
-
/* @__PURE__ */ (0,
|
|
3202
|
-
/* @__PURE__ */ (0,
|
|
3203
|
-
/* @__PURE__ */ (0,
|
|
3336
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Avatar, { size: 32, uri: authorAvatar, name: authorName ?? comment.authorId, style: { marginTop: 6 } }),
|
|
3337
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_native20.View, { style: { flex: 1, minWidth: 0, gap: 4 }, children: [
|
|
3338
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_native20.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.sm }, children: [
|
|
3339
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { style: { fontSize: 14, lineHeight: 18, fontWeight: theme.typography.fontWeight.bold, color: theme.colors.text }, children: authorName ?? "Unknown User" }),
|
|
3340
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, children: formatTimeAgo(comment.createdAt) })
|
|
3204
3341
|
] }),
|
|
3205
|
-
/* @__PURE__ */ (0,
|
|
3342
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { style: { fontSize: 14, lineHeight: 20, color: theme.colors.text }, children: comment.body ?? comment.description ?? "" })
|
|
3206
3343
|
] })
|
|
3207
3344
|
]
|
|
3208
3345
|
}
|
|
@@ -3210,7 +3347,7 @@ function CommentRow({ comment, showDivider }) {
|
|
|
3210
3347
|
}
|
|
3211
3348
|
|
|
3212
3349
|
// src/components/comments/useAppComments.ts
|
|
3213
|
-
var
|
|
3350
|
+
var React20 = __toESM(require("react"));
|
|
3214
3351
|
|
|
3215
3352
|
// src/data/comments/remote.ts
|
|
3216
3353
|
var AppCommentsRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -3282,18 +3419,18 @@ var appCommentsRepository = new AppCommentsRepositoryImpl(appCommentsRemoteDataS
|
|
|
3282
3419
|
|
|
3283
3420
|
// src/components/comments/useAppComments.ts
|
|
3284
3421
|
function useAppComments(appId) {
|
|
3285
|
-
const [comments, setComments] =
|
|
3286
|
-
const [loading, setLoading] =
|
|
3287
|
-
const [sending, setSending] =
|
|
3288
|
-
const [error, setError] =
|
|
3289
|
-
const sortByCreatedAtAsc =
|
|
3422
|
+
const [comments, setComments] = React20.useState([]);
|
|
3423
|
+
const [loading, setLoading] = React20.useState(false);
|
|
3424
|
+
const [sending, setSending] = React20.useState(false);
|
|
3425
|
+
const [error, setError] = React20.useState(null);
|
|
3426
|
+
const sortByCreatedAtAsc = React20.useCallback((items) => {
|
|
3290
3427
|
return [...items].sort((a, b) => {
|
|
3291
3428
|
const at = a.createdAt ? new Date(a.createdAt).getTime() : 0;
|
|
3292
3429
|
const bt = b.createdAt ? new Date(b.createdAt).getTime() : 0;
|
|
3293
3430
|
return at - bt;
|
|
3294
3431
|
});
|
|
3295
3432
|
}, []);
|
|
3296
|
-
const refresh =
|
|
3433
|
+
const refresh = React20.useCallback(async () => {
|
|
3297
3434
|
if (!appId) {
|
|
3298
3435
|
setComments([]);
|
|
3299
3436
|
return;
|
|
@@ -3310,10 +3447,10 @@ function useAppComments(appId) {
|
|
|
3310
3447
|
setLoading(false);
|
|
3311
3448
|
}
|
|
3312
3449
|
}, [appId, sortByCreatedAtAsc]);
|
|
3313
|
-
|
|
3450
|
+
React20.useEffect(() => {
|
|
3314
3451
|
void refresh();
|
|
3315
3452
|
}, [refresh]);
|
|
3316
|
-
const create =
|
|
3453
|
+
const create = React20.useCallback(
|
|
3317
3454
|
async (text) => {
|
|
3318
3455
|
if (!appId) return;
|
|
3319
3456
|
const trimmed = text.trim();
|
|
@@ -3336,11 +3473,11 @@ function useAppComments(appId) {
|
|
|
3336
3473
|
}
|
|
3337
3474
|
|
|
3338
3475
|
// src/components/comments/useAppDetails.ts
|
|
3339
|
-
var
|
|
3476
|
+
var React21 = __toESM(require("react"));
|
|
3340
3477
|
function useAppDetails(appId) {
|
|
3341
|
-
const [app, setApp] =
|
|
3342
|
-
const [loading, setLoading] =
|
|
3343
|
-
|
|
3478
|
+
const [app, setApp] = React21.useState(null);
|
|
3479
|
+
const [loading, setLoading] = React21.useState(false);
|
|
3480
|
+
React21.useEffect(() => {
|
|
3344
3481
|
if (!appId) {
|
|
3345
3482
|
setApp(null);
|
|
3346
3483
|
return;
|
|
@@ -3365,14 +3502,14 @@ function useAppDetails(appId) {
|
|
|
3365
3502
|
}
|
|
3366
3503
|
|
|
3367
3504
|
// src/components/comments/useIosKeyboardSnapFix.ts
|
|
3368
|
-
var
|
|
3369
|
-
var
|
|
3505
|
+
var React22 = __toESM(require("react"));
|
|
3506
|
+
var import_react_native21 = require("react-native");
|
|
3370
3507
|
function useIosKeyboardSnapFix(sheetRef, options) {
|
|
3371
|
-
const [keyboardVisible, setKeyboardVisible] =
|
|
3372
|
-
|
|
3373
|
-
if (
|
|
3374
|
-
const show =
|
|
3375
|
-
const hide =
|
|
3508
|
+
const [keyboardVisible, setKeyboardVisible] = React22.useState(false);
|
|
3509
|
+
React22.useEffect(() => {
|
|
3510
|
+
if (import_react_native21.Platform.OS !== "ios") return;
|
|
3511
|
+
const show = import_react_native21.Keyboard.addListener("keyboardWillShow", () => setKeyboardVisible(true));
|
|
3512
|
+
const hide = import_react_native21.Keyboard.addListener("keyboardWillHide", () => {
|
|
3376
3513
|
var _a;
|
|
3377
3514
|
setKeyboardVisible(false);
|
|
3378
3515
|
const target = (options == null ? void 0 : options.targetIndex) ?? 1;
|
|
@@ -3393,20 +3530,20 @@ function useIosKeyboardSnapFix(sheetRef, options) {
|
|
|
3393
3530
|
}
|
|
3394
3531
|
|
|
3395
3532
|
// src/components/comments/AppCommentsSheet.tsx
|
|
3396
|
-
var
|
|
3533
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3397
3534
|
function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
3398
3535
|
const theme = useTheme();
|
|
3399
3536
|
const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
|
|
3400
|
-
const sheetRef =
|
|
3401
|
-
const snapPoints =
|
|
3402
|
-
const currentIndexRef =
|
|
3537
|
+
const sheetRef = React23.useRef(null);
|
|
3538
|
+
const snapPoints = React23.useMemo(() => ["50%", "90%"], []);
|
|
3539
|
+
const currentIndexRef = React23.useRef(1);
|
|
3403
3540
|
const { comments, loading, sending, error, create, refresh } = useAppComments(appId);
|
|
3404
3541
|
const { app, loading: loadingApp } = useAppDetails(appId);
|
|
3405
3542
|
const { keyboardVisible } = useIosKeyboardSnapFix(sheetRef, {
|
|
3406
3543
|
getCurrentIndex: () => currentIndexRef.current,
|
|
3407
3544
|
targetIndex: 1
|
|
3408
3545
|
});
|
|
3409
|
-
|
|
3546
|
+
React23.useEffect(() => {
|
|
3410
3547
|
var _a, _b;
|
|
3411
3548
|
if (appId) {
|
|
3412
3549
|
(_a = sheetRef.current) == null ? void 0 : _a.present();
|
|
@@ -3415,29 +3552,29 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3415
3552
|
(_b = sheetRef.current) == null ? void 0 : _b.dismiss();
|
|
3416
3553
|
}
|
|
3417
3554
|
}, [appId, refresh]);
|
|
3418
|
-
|
|
3555
|
+
React23.useEffect(() => {
|
|
3419
3556
|
if (!appId) return;
|
|
3420
3557
|
onCountChange == null ? void 0 : onCountChange(comments.length);
|
|
3421
3558
|
}, [appId, comments.length, onCountChange]);
|
|
3422
|
-
const renderBackdrop =
|
|
3423
|
-
(props) => /* @__PURE__ */ (0,
|
|
3559
|
+
const renderBackdrop = React23.useCallback(
|
|
3560
|
+
(props) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_bottom_sheet3.BottomSheetBackdrop, { ...props, disappearsOnIndex: -1, appearsOnIndex: 0, opacity: 0.5 }),
|
|
3424
3561
|
[]
|
|
3425
3562
|
);
|
|
3426
|
-
const handleChange =
|
|
3563
|
+
const handleChange = React23.useCallback(
|
|
3427
3564
|
(index) => {
|
|
3428
3565
|
currentIndexRef.current = index;
|
|
3429
3566
|
if (index === -1) onClose();
|
|
3430
3567
|
},
|
|
3431
3568
|
[onClose]
|
|
3432
3569
|
);
|
|
3433
|
-
const handlePlay =
|
|
3570
|
+
const handlePlay = React23.useCallback(async () => {
|
|
3434
3571
|
var _a;
|
|
3435
3572
|
if (!appId) return;
|
|
3436
3573
|
(_a = sheetRef.current) == null ? void 0 : _a.dismiss();
|
|
3437
3574
|
await (onPlayApp == null ? void 0 : onPlayApp(appId));
|
|
3438
3575
|
onClose();
|
|
3439
3576
|
}, [appId, onClose, onPlayApp]);
|
|
3440
|
-
return /* @__PURE__ */ (0,
|
|
3577
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3441
3578
|
import_bottom_sheet3.BottomSheetModal,
|
|
3442
3579
|
{
|
|
3443
3580
|
ref: sheetRef,
|
|
@@ -3448,17 +3585,17 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3448
3585
|
onChange: handleChange,
|
|
3449
3586
|
backgroundStyle: {
|
|
3450
3587
|
backgroundColor: theme.scheme === "dark" ? "#0B080F" : "#FFFFFF",
|
|
3451
|
-
borderTopLeftRadius:
|
|
3452
|
-
borderTopRightRadius:
|
|
3588
|
+
borderTopLeftRadius: import_react_native22.Platform.OS === "ios" ? 39 : 16,
|
|
3589
|
+
borderTopRightRadius: import_react_native22.Platform.OS === "ios" ? 39 : 16
|
|
3453
3590
|
},
|
|
3454
3591
|
handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
|
|
3455
3592
|
keyboardBehavior: "interactive",
|
|
3456
3593
|
keyboardBlurBehavior: "restore",
|
|
3457
3594
|
android_keyboardInputMode: "adjustResize",
|
|
3458
3595
|
topInset: insets.top,
|
|
3459
|
-
children: /* @__PURE__ */ (0,
|
|
3460
|
-
/* @__PURE__ */ (0,
|
|
3461
|
-
|
|
3596
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native22.View, { style: { flex: 1 }, children: [
|
|
3597
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
3598
|
+
import_react_native22.View,
|
|
3462
3599
|
{
|
|
3463
3600
|
style: {
|
|
3464
3601
|
flexDirection: "row",
|
|
@@ -3470,7 +3607,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3470
3607
|
borderBottomColor: withAlpha(theme.colors.border, 0.1)
|
|
3471
3608
|
},
|
|
3472
3609
|
children: [
|
|
3473
|
-
/* @__PURE__ */ (0,
|
|
3610
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3474
3611
|
Text,
|
|
3475
3612
|
{
|
|
3476
3613
|
numberOfLines: 1,
|
|
@@ -3484,29 +3621,28 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3484
3621
|
children: loadingApp ? "Loading..." : (app == null ? void 0 : app.name) || "Comments"
|
|
3485
3622
|
}
|
|
3486
3623
|
),
|
|
3487
|
-
/* @__PURE__ */ (0,
|
|
3488
|
-
|
|
3624
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3625
|
+
ResettableLiquidGlassView,
|
|
3489
3626
|
{
|
|
3490
3627
|
style: [
|
|
3491
3628
|
{ borderRadius: 24 },
|
|
3492
|
-
!
|
|
3629
|
+
!import_liquid_glass5.isLiquidGlassSupported && { backgroundColor: theme.scheme === "dark" ? "#18181B" : "#F6F6F6" }
|
|
3493
3630
|
],
|
|
3494
3631
|
interactive: true,
|
|
3495
3632
|
effect: "clear",
|
|
3496
|
-
children: /* @__PURE__ */ (0,
|
|
3497
|
-
|
|
3633
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3634
|
+
import_react_native22.View,
|
|
3498
3635
|
{
|
|
3499
3636
|
style: {
|
|
3500
3637
|
width: 32,
|
|
3501
3638
|
height: 32,
|
|
3502
3639
|
borderRadius: 999,
|
|
3503
|
-
backgroundColor: theme.colors.primary,
|
|
3640
|
+
backgroundColor: withAlpha(theme.colors.primary, appId ? 1 : 0.5),
|
|
3504
3641
|
alignItems: "center",
|
|
3505
|
-
justifyContent: "center"
|
|
3506
|
-
opacity: appId ? 1 : 0.5
|
|
3642
|
+
justifyContent: "center"
|
|
3507
3643
|
},
|
|
3508
|
-
children: /* @__PURE__ */ (0,
|
|
3509
|
-
|
|
3644
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3645
|
+
import_react_native22.Pressable,
|
|
3510
3646
|
{
|
|
3511
3647
|
disabled: !appId,
|
|
3512
3648
|
onPress: () => void handlePlay(),
|
|
@@ -3518,9 +3654,9 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3518
3654
|
alignItems: "center",
|
|
3519
3655
|
justifyContent: "center"
|
|
3520
3656
|
},
|
|
3521
|
-
pressed ? {
|
|
3657
|
+
pressed ? { transform: [{ scale: 0.96 }] } : null
|
|
3522
3658
|
],
|
|
3523
|
-
children: /* @__PURE__ */ (0,
|
|
3659
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react_native4.Play, { size: 16, color: theme.colors.onPrimary })
|
|
3524
3660
|
}
|
|
3525
3661
|
)
|
|
3526
3662
|
}
|
|
@@ -3530,7 +3666,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3530
3666
|
]
|
|
3531
3667
|
}
|
|
3532
3668
|
),
|
|
3533
|
-
/* @__PURE__ */ (0,
|
|
3669
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
3534
3670
|
import_bottom_sheet3.BottomSheetScrollView,
|
|
3535
3671
|
{
|
|
3536
3672
|
style: { flex: 1 },
|
|
@@ -3541,13 +3677,13 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3541
3677
|
},
|
|
3542
3678
|
keyboardShouldPersistTaps: "handled",
|
|
3543
3679
|
children: [
|
|
3544
|
-
loading && comments.length === 0 ? /* @__PURE__ */ (0,
|
|
3545
|
-
error ? /* @__PURE__ */ (0,
|
|
3680
|
+
loading && comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.View, { style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.ActivityIndicator, {}) }) : comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.View, { style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Text, { variant: "bodyMuted", style: { textAlign: "center" }, children: "No comments yet" }) }) : comments.map((c, idx) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CommentRow, { comment: c, showDivider: idx < comments.length - 1 }, c.id)),
|
|
3681
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Text, { variant: "captionMuted", style: { marginTop: theme.spacing.lg }, children: "Failed to load comments." }) : null
|
|
3546
3682
|
]
|
|
3547
3683
|
}
|
|
3548
3684
|
),
|
|
3549
|
-
/* @__PURE__ */ (0,
|
|
3550
|
-
|
|
3685
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3686
|
+
import_react_native22.View,
|
|
3551
3687
|
{
|
|
3552
3688
|
style: {
|
|
3553
3689
|
position: "absolute",
|
|
@@ -3556,12 +3692,12 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3556
3692
|
bottom: 0,
|
|
3557
3693
|
paddingHorizontal: theme.spacing.lg,
|
|
3558
3694
|
paddingTop: theme.spacing.sm,
|
|
3559
|
-
paddingBottom:
|
|
3695
|
+
paddingBottom: import_react_native22.Platform.OS === "ios" ? keyboardVisible ? theme.spacing.lg : insets.bottom : insets.bottom + 10,
|
|
3560
3696
|
borderTopWidth: 1,
|
|
3561
3697
|
borderTopColor: withAlpha(theme.colors.border, 0.1),
|
|
3562
3698
|
backgroundColor: withAlpha(theme.colors.background, 0.8)
|
|
3563
3699
|
},
|
|
3564
|
-
children: /* @__PURE__ */ (0,
|
|
3700
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3565
3701
|
ChatComposer,
|
|
3566
3702
|
{
|
|
3567
3703
|
placeholder: "Write a comment...",
|
|
@@ -3570,7 +3706,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3570
3706
|
useBottomSheetTextInput: true,
|
|
3571
3707
|
onSend: async (text) => {
|
|
3572
3708
|
await create(text);
|
|
3573
|
-
|
|
3709
|
+
import_react_native22.Keyboard.dismiss();
|
|
3574
3710
|
}
|
|
3575
3711
|
}
|
|
3576
3712
|
)
|
|
@@ -3582,17 +3718,17 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3582
3718
|
}
|
|
3583
3719
|
|
|
3584
3720
|
// src/studio/ui/PreviewPanel.tsx
|
|
3585
|
-
var
|
|
3721
|
+
var import_react_native43 = require("react-native");
|
|
3586
3722
|
|
|
3587
3723
|
// src/components/preview/PreviewPage.tsx
|
|
3588
|
-
var
|
|
3724
|
+
var import_react_native23 = require("react-native");
|
|
3589
3725
|
var import_bottom_sheet4 = require("@gorhom/bottom-sheet");
|
|
3590
|
-
var
|
|
3726
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3591
3727
|
function PreviewPage({ header, children, contentStyle }) {
|
|
3592
3728
|
const theme = useTheme();
|
|
3593
|
-
return /* @__PURE__ */ (0,
|
|
3594
|
-
header ? /* @__PURE__ */ (0,
|
|
3595
|
-
/* @__PURE__ */ (0,
|
|
3729
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react_native23.View, { style: { flex: 1 }, children: [
|
|
3730
|
+
header ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native23.View, { children: header }) : null,
|
|
3731
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3596
3732
|
import_bottom_sheet4.BottomSheetScrollView,
|
|
3597
3733
|
{
|
|
3598
3734
|
style: { flex: 1 },
|
|
@@ -3611,15 +3747,15 @@ function PreviewPage({ header, children, contentStyle }) {
|
|
|
3611
3747
|
}
|
|
3612
3748
|
|
|
3613
3749
|
// src/studio/ui/preview-panel/PreviewPanelHeader.tsx
|
|
3614
|
-
var
|
|
3750
|
+
var import_react_native26 = require("react-native");
|
|
3615
3751
|
|
|
3616
3752
|
// src/components/studio-sheet/StudioSheetHeader.tsx
|
|
3617
|
-
var
|
|
3618
|
-
var
|
|
3753
|
+
var import_react_native24 = require("react-native");
|
|
3754
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3619
3755
|
function StudioSheetHeader({ left, center, right, style }) {
|
|
3620
3756
|
const theme = useTheme();
|
|
3621
|
-
return /* @__PURE__ */ (0,
|
|
3622
|
-
|
|
3757
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
3758
|
+
import_react_native24.View,
|
|
3623
3759
|
{
|
|
3624
3760
|
style: [
|
|
3625
3761
|
{
|
|
@@ -3632,19 +3768,19 @@ function StudioSheetHeader({ left, center, right, style }) {
|
|
|
3632
3768
|
style
|
|
3633
3769
|
],
|
|
3634
3770
|
children: [
|
|
3635
|
-
/* @__PURE__ */ (0,
|
|
3636
|
-
/* @__PURE__ */ (0,
|
|
3637
|
-
/* @__PURE__ */ (0,
|
|
3771
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native24.View, { style: { flexDirection: "row", alignItems: "center" }, children: left }),
|
|
3772
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native24.View, { style: { flex: 1, alignItems: "center" }, children: center }),
|
|
3773
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native24.View, { style: { flexDirection: "row", alignItems: "center" }, children: right })
|
|
3638
3774
|
]
|
|
3639
3775
|
}
|
|
3640
3776
|
);
|
|
3641
3777
|
}
|
|
3642
3778
|
|
|
3643
3779
|
// src/components/studio-sheet/StudioSheetHeaderIconButton.tsx
|
|
3644
|
-
var
|
|
3645
|
-
var
|
|
3646
|
-
var
|
|
3647
|
-
var
|
|
3780
|
+
var React24 = __toESM(require("react"));
|
|
3781
|
+
var import_react_native25 = require("react-native");
|
|
3782
|
+
var import_liquid_glass6 = require("@callstack/liquid-glass");
|
|
3783
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3648
3784
|
function StudioSheetHeaderIconButton({
|
|
3649
3785
|
onPress,
|
|
3650
3786
|
disabled,
|
|
@@ -3656,19 +3792,20 @@ function StudioSheetHeaderIconButton({
|
|
|
3656
3792
|
}) {
|
|
3657
3793
|
const theme = useTheme();
|
|
3658
3794
|
const size = 44;
|
|
3659
|
-
const [pressed, setPressed] =
|
|
3795
|
+
const [pressed, setPressed] = React24.useState(false);
|
|
3660
3796
|
const solidBg = intent === "danger" ? theme.colors.danger : intent === "primary" ? theme.colors.primary : theme.colors.neutral;
|
|
3661
3797
|
const glassFallbackBg = theme.scheme === "dark" ? "#18181B" : "#F6F6F6";
|
|
3662
3798
|
const glassInnerBg = intent === "danger" ? theme.colors.danger : theme.colors.primary;
|
|
3663
3799
|
const resolvedOpacity = disabled ? 0.6 : pressed ? 0.9 : 1;
|
|
3664
|
-
|
|
3665
|
-
|
|
3800
|
+
const glassBg = withAlpha(glassInnerBg, resolvedOpacity);
|
|
3801
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native25.View, { style, children: appearance === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3802
|
+
ResettableLiquidGlassView,
|
|
3666
3803
|
{
|
|
3667
|
-
style: [{ borderRadius: 100 }, !
|
|
3804
|
+
style: [{ borderRadius: 100 }, !import_liquid_glass6.isLiquidGlassSupported && { backgroundColor: glassFallbackBg }],
|
|
3668
3805
|
interactive: true,
|
|
3669
3806
|
effect: "clear",
|
|
3670
|
-
children: /* @__PURE__ */ (0,
|
|
3671
|
-
|
|
3807
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3808
|
+
import_react_native25.View,
|
|
3672
3809
|
{
|
|
3673
3810
|
style: {
|
|
3674
3811
|
width: size,
|
|
@@ -3676,11 +3813,10 @@ function StudioSheetHeaderIconButton({
|
|
|
3676
3813
|
borderRadius: 100,
|
|
3677
3814
|
alignItems: "center",
|
|
3678
3815
|
justifyContent: "center",
|
|
3679
|
-
backgroundColor:
|
|
3680
|
-
opacity: resolvedOpacity
|
|
3816
|
+
backgroundColor: glassBg
|
|
3681
3817
|
},
|
|
3682
|
-
children: /* @__PURE__ */ (0,
|
|
3683
|
-
|
|
3818
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3819
|
+
import_react_native25.Pressable,
|
|
3684
3820
|
{
|
|
3685
3821
|
accessibilityRole: "button",
|
|
3686
3822
|
accessibilityLabel,
|
|
@@ -3698,8 +3834,8 @@ function StudioSheetHeaderIconButton({
|
|
|
3698
3834
|
}
|
|
3699
3835
|
)
|
|
3700
3836
|
}
|
|
3701
|
-
) : /* @__PURE__ */ (0,
|
|
3702
|
-
|
|
3837
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3838
|
+
import_react_native25.View,
|
|
3703
3839
|
{
|
|
3704
3840
|
style: {
|
|
3705
3841
|
width: size,
|
|
@@ -3710,8 +3846,8 @@ function StudioSheetHeaderIconButton({
|
|
|
3710
3846
|
backgroundColor: solidBg,
|
|
3711
3847
|
opacity: resolvedOpacity
|
|
3712
3848
|
},
|
|
3713
|
-
children: /* @__PURE__ */ (0,
|
|
3714
|
-
|
|
3849
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3850
|
+
import_react_native25.Pressable,
|
|
3715
3851
|
{
|
|
3716
3852
|
accessibilityRole: "button",
|
|
3717
3853
|
accessibilityLabel,
|
|
@@ -3731,15 +3867,15 @@ function StudioSheetHeaderIconButton({
|
|
|
3731
3867
|
}
|
|
3732
3868
|
|
|
3733
3869
|
// src/studio/ui/preview-panel/PreviewPanelHeader.tsx
|
|
3734
|
-
var
|
|
3870
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
3735
3871
|
function PreviewPanelHeader({ isOwner, onClose, onNavigateHome, onGoToChat }) {
|
|
3736
|
-
return /* @__PURE__ */ (0,
|
|
3872
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3737
3873
|
StudioSheetHeader,
|
|
3738
3874
|
{
|
|
3739
|
-
left: onNavigateHome ? /* @__PURE__ */ (0,
|
|
3875
|
+
left: onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", appearance: "glass", intent: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IconHome, { size: 20, colorToken: "onPrimary" }) }) : null,
|
|
3740
3876
|
center: null,
|
|
3741
|
-
right: /* @__PURE__ */ (0,
|
|
3742
|
-
isOwner ? /* @__PURE__ */ (0,
|
|
3877
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native26.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
3878
|
+
isOwner ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3743
3879
|
StudioSheetHeaderIconButton,
|
|
3744
3880
|
{
|
|
3745
3881
|
onPress: onGoToChat,
|
|
@@ -3747,21 +3883,21 @@ function PreviewPanelHeader({ isOwner, onClose, onNavigateHome, onGoToChat }) {
|
|
|
3747
3883
|
intent: "primary",
|
|
3748
3884
|
appearance: "glass",
|
|
3749
3885
|
style: { marginRight: 8 },
|
|
3750
|
-
children: /* @__PURE__ */ (0,
|
|
3886
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IconChat, { size: 20, colorToken: "onPrimary" })
|
|
3751
3887
|
}
|
|
3752
3888
|
) : null,
|
|
3753
|
-
/* @__PURE__ */ (0,
|
|
3889
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", appearance: "glass", intent: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IconClose, { size: 20, colorToken: "onPrimary" }) })
|
|
3754
3890
|
] })
|
|
3755
3891
|
}
|
|
3756
3892
|
);
|
|
3757
3893
|
}
|
|
3758
3894
|
|
|
3759
3895
|
// src/components/preview/PreviewHeroCard.tsx
|
|
3760
|
-
var
|
|
3896
|
+
var import_react_native28 = require("react-native");
|
|
3761
3897
|
|
|
3762
3898
|
// src/components/primitives/Surface.tsx
|
|
3763
|
-
var
|
|
3764
|
-
var
|
|
3899
|
+
var import_react_native27 = require("react-native");
|
|
3900
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
3765
3901
|
function backgroundFor(variant, theme) {
|
|
3766
3902
|
const { colors } = theme;
|
|
3767
3903
|
switch (variant) {
|
|
@@ -3778,8 +3914,8 @@ function backgroundFor(variant, theme) {
|
|
|
3778
3914
|
}
|
|
3779
3915
|
function Surface({ variant = "surface", border = false, style, ...props }) {
|
|
3780
3916
|
const theme = useTheme();
|
|
3781
|
-
return /* @__PURE__ */ (0,
|
|
3782
|
-
|
|
3917
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3918
|
+
import_react_native27.View,
|
|
3783
3919
|
{
|
|
3784
3920
|
...props,
|
|
3785
3921
|
style: [
|
|
@@ -3792,12 +3928,12 @@ function Surface({ variant = "surface", border = false, style, ...props }) {
|
|
|
3792
3928
|
}
|
|
3793
3929
|
|
|
3794
3930
|
// src/components/primitives/Card.tsx
|
|
3795
|
-
var
|
|
3931
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
3796
3932
|
function Card({ variant = "surface", padded = true, border = true, style, ...props }) {
|
|
3797
3933
|
const theme = useTheme();
|
|
3798
3934
|
const radius = theme.radii.lg;
|
|
3799
3935
|
const padding = padded ? theme.spacing.lg : 0;
|
|
3800
|
-
return /* @__PURE__ */ (0,
|
|
3936
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3801
3937
|
Surface,
|
|
3802
3938
|
{
|
|
3803
3939
|
...props,
|
|
@@ -3809,7 +3945,7 @@ function Card({ variant = "surface", padded = true, border = true, style, ...pro
|
|
|
3809
3945
|
}
|
|
3810
3946
|
|
|
3811
3947
|
// src/components/preview/PreviewHeroCard.tsx
|
|
3812
|
-
var
|
|
3948
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
3813
3949
|
function PreviewHeroCard({
|
|
3814
3950
|
aspectRatio = 4 / 3,
|
|
3815
3951
|
overlayTopLeft,
|
|
@@ -3820,7 +3956,7 @@ function PreviewHeroCard({
|
|
|
3820
3956
|
}) {
|
|
3821
3957
|
const theme = useTheme();
|
|
3822
3958
|
const radius = 16;
|
|
3823
|
-
return /* @__PURE__ */ (0,
|
|
3959
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3824
3960
|
Card,
|
|
3825
3961
|
{
|
|
3826
3962
|
variant: "surfaceRaised",
|
|
@@ -3835,32 +3971,32 @@ function PreviewHeroCard({
|
|
|
3835
3971
|
},
|
|
3836
3972
|
style
|
|
3837
3973
|
],
|
|
3838
|
-
children: /* @__PURE__ */ (0,
|
|
3839
|
-
background ? /* @__PURE__ */ (0,
|
|
3840
|
-
image ? /* @__PURE__ */ (0,
|
|
3841
|
-
overlayTopLeft ? /* @__PURE__ */ (0,
|
|
3842
|
-
overlayBottom ? /* @__PURE__ */ (0,
|
|
3974
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react_native28.View, { style: { flex: 1 }, children: [
|
|
3975
|
+
background ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native28.View, { style: { position: "absolute", inset: 0 }, children: background }) : null,
|
|
3976
|
+
image ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native28.View, { style: { position: "absolute", inset: 0 }, children: image }) : null,
|
|
3977
|
+
overlayTopLeft ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native28.View, { style: { position: "absolute", top: theme.spacing.sm, left: theme.spacing.sm, zIndex: 2 }, children: overlayTopLeft }) : null,
|
|
3978
|
+
overlayBottom ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native28.View, { style: { flex: 1, justifyContent: "flex-end" }, children: overlayBottom }) : null
|
|
3843
3979
|
] })
|
|
3844
3980
|
}
|
|
3845
3981
|
);
|
|
3846
3982
|
}
|
|
3847
3983
|
|
|
3848
3984
|
// src/components/preview/PreviewPlaceholder.tsx
|
|
3849
|
-
var
|
|
3850
|
-
var
|
|
3985
|
+
var React25 = __toESM(require("react"));
|
|
3986
|
+
var import_react_native29 = require("react-native");
|
|
3851
3987
|
var import_expo_linear_gradient2 = require("expo-linear-gradient");
|
|
3852
|
-
var
|
|
3988
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
3853
3989
|
function PreviewPlaceholder({ visible, style }) {
|
|
3854
3990
|
if (!visible) return null;
|
|
3855
|
-
const opacityAnim =
|
|
3856
|
-
|
|
3991
|
+
const opacityAnim = React25.useRef(new import_react_native29.Animated.Value(0)).current;
|
|
3992
|
+
React25.useEffect(() => {
|
|
3857
3993
|
if (!visible) return;
|
|
3858
|
-
const animation =
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3994
|
+
const animation = import_react_native29.Animated.loop(
|
|
3995
|
+
import_react_native29.Animated.sequence([
|
|
3996
|
+
import_react_native29.Animated.timing(opacityAnim, { toValue: 1, duration: 1500, useNativeDriver: true }),
|
|
3997
|
+
import_react_native29.Animated.timing(opacityAnim, { toValue: 2, duration: 1500, useNativeDriver: true }),
|
|
3998
|
+
import_react_native29.Animated.timing(opacityAnim, { toValue: 3, duration: 1500, useNativeDriver: true }),
|
|
3999
|
+
import_react_native29.Animated.timing(opacityAnim, { toValue: 0, duration: 1500, useNativeDriver: true })
|
|
3864
4000
|
])
|
|
3865
4001
|
);
|
|
3866
4002
|
animation.start();
|
|
@@ -3870,8 +4006,8 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3870
4006
|
const opacity2 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 1, 0, 0] });
|
|
3871
4007
|
const opacity3 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 1, 0] });
|
|
3872
4008
|
const opacity4 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 0, 1] });
|
|
3873
|
-
return /* @__PURE__ */ (0,
|
|
3874
|
-
/* @__PURE__ */ (0,
|
|
4009
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
4010
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native29.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3875
4011
|
import_expo_linear_gradient2.LinearGradient,
|
|
3876
4012
|
{
|
|
3877
4013
|
colors: ["rgba(98, 0, 238, 0.45)", "rgba(168, 85, 247, 0.35)"],
|
|
@@ -3880,7 +4016,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3880
4016
|
style: { width: "100%", height: "100%" }
|
|
3881
4017
|
}
|
|
3882
4018
|
) }),
|
|
3883
|
-
/* @__PURE__ */ (0,
|
|
4019
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native29.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity2 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3884
4020
|
import_expo_linear_gradient2.LinearGradient,
|
|
3885
4021
|
{
|
|
3886
4022
|
colors: ["rgba(168, 85, 247, 0.45)", "rgba(139, 92, 246, 0.35)"],
|
|
@@ -3889,7 +4025,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3889
4025
|
style: { width: "100%", height: "100%" }
|
|
3890
4026
|
}
|
|
3891
4027
|
) }),
|
|
3892
|
-
/* @__PURE__ */ (0,
|
|
4028
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native29.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity3 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3893
4029
|
import_expo_linear_gradient2.LinearGradient,
|
|
3894
4030
|
{
|
|
3895
4031
|
colors: ["rgba(139, 92, 246, 0.45)", "rgba(126, 34, 206, 0.35)"],
|
|
@@ -3898,7 +4034,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3898
4034
|
style: { width: "100%", height: "100%" }
|
|
3899
4035
|
}
|
|
3900
4036
|
) }),
|
|
3901
|
-
/* @__PURE__ */ (0,
|
|
4037
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native29.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity4 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3902
4038
|
import_expo_linear_gradient2.LinearGradient,
|
|
3903
4039
|
{
|
|
3904
4040
|
colors: ["rgba(126, 34, 206, 0.45)", "rgba(98, 0, 238, 0.35)"],
|
|
@@ -3911,12 +4047,12 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3911
4047
|
}
|
|
3912
4048
|
|
|
3913
4049
|
// src/components/preview/PreviewImage.tsx
|
|
3914
|
-
var
|
|
3915
|
-
var
|
|
4050
|
+
var import_react_native30 = require("react-native");
|
|
4051
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
3916
4052
|
function PreviewImage({ uri, onLoad, style }) {
|
|
3917
4053
|
if (!uri) return null;
|
|
3918
|
-
return /* @__PURE__ */ (0,
|
|
3919
|
-
|
|
4054
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
4055
|
+
import_react_native30.Image,
|
|
3920
4056
|
{
|
|
3921
4057
|
source: { uri },
|
|
3922
4058
|
resizeMode: "cover",
|
|
@@ -3927,15 +4063,15 @@ function PreviewImage({ uri, onLoad, style }) {
|
|
|
3927
4063
|
}
|
|
3928
4064
|
|
|
3929
4065
|
// src/components/preview/StatsBar.tsx
|
|
3930
|
-
var
|
|
3931
|
-
var
|
|
4066
|
+
var import_react_native31 = require("react-native");
|
|
4067
|
+
var import_liquid_glass7 = require("@callstack/liquid-glass");
|
|
3932
4068
|
var import_lucide_react_native5 = require("lucide-react-native");
|
|
3933
4069
|
|
|
3934
4070
|
// src/components/icons/MergeIcon.tsx
|
|
3935
4071
|
var import_react_native_svg2 = __toESM(require("react-native-svg"));
|
|
3936
|
-
var
|
|
4072
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
3937
4073
|
function MergeIcon({ color = "currentColor", width = 24, height = 24, ...props }) {
|
|
3938
|
-
return /* @__PURE__ */ (0,
|
|
4074
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_native_svg2.default, { viewBox: "0 0 486 486", width, height, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
3939
4075
|
import_react_native_svg2.Path,
|
|
3940
4076
|
{
|
|
3941
4077
|
d: "M237.025 0H243.664C254.876 95.0361 275.236 175.597 304.743 241.684C334.249 307.478 367.002 357.774 403 392.572L389.722 486C361.691 458.22 338.233 429.417 319.349 399.59C300.464 369.764 284.531 335.843 271.548 297.829C258.565 259.522 246.615 214.343 235.697 162.292L237.91 161.415C228.468 214.928 217.993 261.569 206.485 301.338C194.978 341.107 179.634 375.904 160.455 405.731C141.571 435.265 115.752 462.022 83 486L96.278 392.572C124.014 369.179 147.62 336.72 167.094 295.197C186.864 253.381 202.65 206.886 214.452 155.713C226.255 104.247 233.779 52.343 237.025 0Z",
|
|
@@ -3945,7 +4081,7 @@ function MergeIcon({ color = "currentColor", width = 24, height = 24, ...props }
|
|
|
3945
4081
|
}
|
|
3946
4082
|
|
|
3947
4083
|
// src/components/preview/StatsBar.tsx
|
|
3948
|
-
var
|
|
4084
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
3949
4085
|
function StatsBar({
|
|
3950
4086
|
likeCount,
|
|
3951
4087
|
commentCount,
|
|
@@ -3959,33 +4095,33 @@ function StatsBar({
|
|
|
3959
4095
|
}) {
|
|
3960
4096
|
const theme = useTheme();
|
|
3961
4097
|
const statsBgColor = theme.scheme === "dark" ? "rgba(24, 24, 27, 0.5)" : "rgba(255, 255, 255, 0.5)";
|
|
3962
|
-
return /* @__PURE__ */ (0,
|
|
3963
|
-
|
|
4098
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
4099
|
+
import_react_native31.View,
|
|
3964
4100
|
{
|
|
3965
4101
|
style: [
|
|
3966
4102
|
{ position: "absolute", bottom: 12, width: "100%", paddingHorizontal: 12 },
|
|
3967
4103
|
centered && { alignItems: "center" },
|
|
3968
4104
|
style
|
|
3969
4105
|
],
|
|
3970
|
-
children: /* @__PURE__ */ (0,
|
|
3971
|
-
|
|
4106
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
4107
|
+
ResettableLiquidGlassView,
|
|
3972
4108
|
{
|
|
3973
4109
|
style: [
|
|
3974
4110
|
{ borderRadius: 100, overflow: "hidden" },
|
|
3975
4111
|
fixedWidth ? { width: fixedWidth } : void 0,
|
|
3976
|
-
!
|
|
4112
|
+
!import_liquid_glass7.isLiquidGlassSupported && { backgroundColor: statsBgColor }
|
|
3977
4113
|
],
|
|
3978
4114
|
effect: "clear",
|
|
3979
|
-
children: /* @__PURE__ */ (0,
|
|
3980
|
-
/* @__PURE__ */ (0,
|
|
3981
|
-
|
|
4115
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native31.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16 }, children: [
|
|
4116
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
4117
|
+
import_react_native31.Pressable,
|
|
3982
4118
|
{
|
|
3983
4119
|
disabled: !onPressLike,
|
|
3984
4120
|
onPress: onPressLike,
|
|
3985
4121
|
hitSlop: 8,
|
|
3986
4122
|
style: { paddingVertical: 8 },
|
|
3987
|
-
children: /* @__PURE__ */ (0,
|
|
3988
|
-
/* @__PURE__ */ (0,
|
|
4123
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native31.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4124
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
3989
4125
|
import_lucide_react_native5.Heart,
|
|
3990
4126
|
{
|
|
3991
4127
|
size: 16,
|
|
@@ -3994,8 +4130,8 @@ function StatsBar({
|
|
|
3994
4130
|
fill: isLiked ? theme.colors.danger : "transparent"
|
|
3995
4131
|
}
|
|
3996
4132
|
),
|
|
3997
|
-
/* @__PURE__ */ (0,
|
|
3998
|
-
/* @__PURE__ */ (0,
|
|
4133
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_native31.View, { style: { width: 4 } }),
|
|
4134
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
3999
4135
|
Text,
|
|
4000
4136
|
{
|
|
4001
4137
|
variant: "caption",
|
|
@@ -4009,24 +4145,24 @@ function StatsBar({
|
|
|
4009
4145
|
] })
|
|
4010
4146
|
}
|
|
4011
4147
|
),
|
|
4012
|
-
/* @__PURE__ */ (0,
|
|
4013
|
-
|
|
4148
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
4149
|
+
import_react_native31.Pressable,
|
|
4014
4150
|
{
|
|
4015
4151
|
disabled: !onPressComments,
|
|
4016
4152
|
onPress: onPressComments,
|
|
4017
4153
|
hitSlop: 8,
|
|
4018
4154
|
style: { paddingVertical: 8 },
|
|
4019
|
-
children: /* @__PURE__ */ (0,
|
|
4020
|
-
/* @__PURE__ */ (0,
|
|
4021
|
-
/* @__PURE__ */ (0,
|
|
4022
|
-
/* @__PURE__ */ (0,
|
|
4155
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native31.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4156
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react_native5.MessageCircle, { size: 16, strokeWidth: 2.5, color: "#FFFFFF" }),
|
|
4157
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_native31.View, { style: { width: 4 } }),
|
|
4158
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: commentCount })
|
|
4023
4159
|
] })
|
|
4024
4160
|
}
|
|
4025
4161
|
),
|
|
4026
|
-
/* @__PURE__ */ (0,
|
|
4027
|
-
/* @__PURE__ */ (0,
|
|
4028
|
-
/* @__PURE__ */ (0,
|
|
4029
|
-
/* @__PURE__ */ (0,
|
|
4162
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native31.View, { style: { flexDirection: "row", alignItems: "center", paddingVertical: 8 }, children: [
|
|
4163
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_native31.View, { style: { transform: [{ scaleY: -1 }] }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MergeIcon, { width: 14, height: 14, color: "#FFFFFF" }) }),
|
|
4164
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_native31.View, { style: { width: 4 } }),
|
|
4165
|
+
/* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: forkCount })
|
|
4030
4166
|
] })
|
|
4031
4167
|
] })
|
|
4032
4168
|
}
|
|
@@ -4036,7 +4172,7 @@ function StatsBar({
|
|
|
4036
4172
|
}
|
|
4037
4173
|
|
|
4038
4174
|
// src/components/preview/PreviewStatusBadge.tsx
|
|
4039
|
-
var
|
|
4175
|
+
var import_react_native32 = require("react-native");
|
|
4040
4176
|
var import_lucide_react_native6 = require("lucide-react-native");
|
|
4041
4177
|
|
|
4042
4178
|
// src/data/apps/types.ts
|
|
@@ -4051,7 +4187,7 @@ var APP_STATUS_LABEL = {
|
|
|
4051
4187
|
};
|
|
4052
4188
|
|
|
4053
4189
|
// src/components/preview/PreviewStatusBadge.tsx
|
|
4054
|
-
var
|
|
4190
|
+
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
4055
4191
|
var STATUS_BG = {
|
|
4056
4192
|
ready: "#10B981",
|
|
4057
4193
|
// emerald-500
|
|
@@ -4080,8 +4216,8 @@ var STATUS_ICON = {
|
|
|
4080
4216
|
function PreviewStatusBadge({ status }) {
|
|
4081
4217
|
const IconComp = STATUS_ICON[status];
|
|
4082
4218
|
const label = APP_STATUS_LABEL[status] ?? status;
|
|
4083
|
-
return /* @__PURE__ */ (0,
|
|
4084
|
-
|
|
4219
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
4220
|
+
import_react_native32.View,
|
|
4085
4221
|
{
|
|
4086
4222
|
style: {
|
|
4087
4223
|
flexDirection: "row",
|
|
@@ -4092,15 +4228,15 @@ function PreviewStatusBadge({ status }) {
|
|
|
4092
4228
|
backgroundColor: STATUS_BG[status]
|
|
4093
4229
|
},
|
|
4094
4230
|
children: [
|
|
4095
|
-
/* @__PURE__ */ (0,
|
|
4096
|
-
/* @__PURE__ */ (0,
|
|
4231
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(IconComp, { size: 12, color: "#FFFFFF", style: { marginRight: 4 } }),
|
|
4232
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Text, { style: { color: "#FFFFFF", fontSize: 11, lineHeight: 14 }, children: label })
|
|
4097
4233
|
]
|
|
4098
4234
|
}
|
|
4099
4235
|
);
|
|
4100
4236
|
}
|
|
4101
4237
|
|
|
4102
4238
|
// src/studio/ui/preview-panel/PreviewHeroSection.tsx
|
|
4103
|
-
var
|
|
4239
|
+
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
4104
4240
|
function PreviewHeroSection({
|
|
4105
4241
|
appStatus,
|
|
4106
4242
|
showProcessing,
|
|
@@ -4109,13 +4245,13 @@ function PreviewHeroSection({
|
|
|
4109
4245
|
onImageLoad,
|
|
4110
4246
|
stats
|
|
4111
4247
|
}) {
|
|
4112
|
-
return /* @__PURE__ */ (0,
|
|
4248
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
4113
4249
|
PreviewHeroCard,
|
|
4114
4250
|
{
|
|
4115
|
-
overlayTopLeft: showProcessing ? /* @__PURE__ */ (0,
|
|
4116
|
-
background: /* @__PURE__ */ (0,
|
|
4117
|
-
image: /* @__PURE__ */ (0,
|
|
4118
|
-
overlayBottom: /* @__PURE__ */ (0,
|
|
4251
|
+
overlayTopLeft: showProcessing ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(PreviewStatusBadge, { status: appStatus }) : null,
|
|
4252
|
+
background: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(PreviewPlaceholder, { visible: !imageLoaded }),
|
|
4253
|
+
image: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(PreviewImage, { uri: imageUrl, onLoad: onImageLoad }),
|
|
4254
|
+
overlayBottom: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
4119
4255
|
StatsBar,
|
|
4120
4256
|
{
|
|
4121
4257
|
likeCount: stats.likeCount,
|
|
@@ -4134,11 +4270,11 @@ function PreviewHeroSection({
|
|
|
4134
4270
|
}
|
|
4135
4271
|
|
|
4136
4272
|
// src/studio/ui/preview-panel/PreviewMetaSection.tsx
|
|
4137
|
-
var
|
|
4273
|
+
var import_react_native34 = require("react-native");
|
|
4138
4274
|
|
|
4139
4275
|
// src/components/preview/PreviewMetaRow.tsx
|
|
4140
|
-
var
|
|
4141
|
-
var
|
|
4276
|
+
var import_react_native33 = require("react-native");
|
|
4277
|
+
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
4142
4278
|
function PreviewMetaRow({
|
|
4143
4279
|
avatarUri,
|
|
4144
4280
|
creatorName,
|
|
@@ -4149,11 +4285,11 @@ function PreviewMetaRow({
|
|
|
4149
4285
|
style
|
|
4150
4286
|
}) {
|
|
4151
4287
|
const theme = useTheme();
|
|
4152
|
-
return /* @__PURE__ */ (0,
|
|
4153
|
-
/* @__PURE__ */ (0,
|
|
4154
|
-
/* @__PURE__ */ (0,
|
|
4155
|
-
/* @__PURE__ */ (0,
|
|
4156
|
-
/* @__PURE__ */ (0,
|
|
4288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native33.View, { style: [{ alignSelf: "stretch" }, style], children: [
|
|
4289
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native33.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4290
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Avatar, { uri: avatarUri, name: creatorName, size: 24, style: { marginRight: theme.spacing.sm } }),
|
|
4291
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native33.View, { style: { flexDirection: "row", alignItems: "center", flex: 1, minWidth: 0, marginRight: theme.spacing.sm }, children: [
|
|
4292
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4157
4293
|
Text,
|
|
4158
4294
|
{
|
|
4159
4295
|
numberOfLines: 1,
|
|
@@ -4167,11 +4303,11 @@ function PreviewMetaRow({
|
|
|
4167
4303
|
children: title
|
|
4168
4304
|
}
|
|
4169
4305
|
),
|
|
4170
|
-
tag ? /* @__PURE__ */ (0,
|
|
4306
|
+
tag ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_native33.View, { style: { marginLeft: theme.spacing.sm }, children: tag }) : null
|
|
4171
4307
|
] }),
|
|
4172
|
-
rightMetric ? /* @__PURE__ */ (0,
|
|
4308
|
+
rightMetric ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_native33.View, { children: rightMetric }) : null
|
|
4173
4309
|
] }),
|
|
4174
|
-
subtitle ? /* @__PURE__ */ (0,
|
|
4310
|
+
subtitle ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4175
4311
|
Text,
|
|
4176
4312
|
{
|
|
4177
4313
|
numberOfLines: 2,
|
|
@@ -4214,20 +4350,20 @@ function statusDescription(status, statusError) {
|
|
|
4214
4350
|
}
|
|
4215
4351
|
|
|
4216
4352
|
// src/studio/ui/preview-panel/PreviewMetaSection.tsx
|
|
4217
|
-
var
|
|
4353
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
4218
4354
|
function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
|
|
4219
4355
|
var _a;
|
|
4220
4356
|
const theme = useTheme();
|
|
4221
|
-
return /* @__PURE__ */ (0,
|
|
4357
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
4222
4358
|
PreviewMetaRow,
|
|
4223
4359
|
{
|
|
4224
4360
|
title: app.name,
|
|
4225
4361
|
subtitle: app.description,
|
|
4226
4362
|
avatarUri: (creator == null ? void 0 : creator.avatar) ?? null,
|
|
4227
4363
|
creatorName: (creator == null ? void 0 : creator.name) ?? null,
|
|
4228
|
-
tag: isOwner || app.forkedFromAppId ? /* @__PURE__ */ (0,
|
|
4229
|
-
rightMetric: /* @__PURE__ */ (0,
|
|
4230
|
-
|
|
4364
|
+
tag: isOwner || app.forkedFromAppId ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_native34.View, { style: { paddingHorizontal: 8, paddingVertical: 2, borderRadius: 999, backgroundColor: "#3700B3" }, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Text, { variant: "caption", style: { color: "#fff", fontWeight: theme.typography.fontWeight.semibold }, children: app.forkedFromAppId ? "Remix" : "Owner" }) }) : null,
|
|
4365
|
+
rightMetric: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
|
|
4366
|
+
import_react_native34.View,
|
|
4231
4367
|
{
|
|
4232
4368
|
style: {
|
|
4233
4369
|
flexDirection: "row",
|
|
@@ -4238,7 +4374,7 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
|
|
|
4238
4374
|
backgroundColor: withAlpha(theme.colors.neutral, 0.3)
|
|
4239
4375
|
},
|
|
4240
4376
|
children: [
|
|
4241
|
-
/* @__PURE__ */ (0,
|
|
4377
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
4242
4378
|
Text,
|
|
4243
4379
|
{
|
|
4244
4380
|
style: {
|
|
@@ -4251,7 +4387,7 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
|
|
|
4251
4387
|
children: formatCount(downloadsCount ?? ((_a = app.insights) == null ? void 0 : _a.totalDownloads) ?? 0)
|
|
4252
4388
|
}
|
|
4253
4389
|
),
|
|
4254
|
-
/* @__PURE__ */ (0,
|
|
4390
|
+
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)(IconPlay, { size: 14, colorToken: "textMuted", fill: theme.colors.textMuted })
|
|
4255
4391
|
]
|
|
4256
4392
|
}
|
|
4257
4393
|
),
|
|
@@ -4261,11 +4397,11 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
|
|
|
4261
4397
|
}
|
|
4262
4398
|
|
|
4263
4399
|
// src/studio/ui/preview-panel/PreviewCustomizeSection.tsx
|
|
4264
|
-
var
|
|
4400
|
+
var import_react_native36 = require("react-native");
|
|
4265
4401
|
|
|
4266
4402
|
// src/studio/ui/preview-panel/PressableCardRow.tsx
|
|
4267
|
-
var
|
|
4268
|
-
var
|
|
4403
|
+
var import_react_native35 = require("react-native");
|
|
4404
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
4269
4405
|
function PressableCardRow({
|
|
4270
4406
|
accessibilityLabel,
|
|
4271
4407
|
onPress,
|
|
@@ -4276,31 +4412,31 @@ function PressableCardRow({
|
|
|
4276
4412
|
right,
|
|
4277
4413
|
style
|
|
4278
4414
|
}) {
|
|
4279
|
-
return /* @__PURE__ */ (0,
|
|
4280
|
-
|
|
4415
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4416
|
+
import_react_native35.Pressable,
|
|
4281
4417
|
{
|
|
4282
4418
|
accessibilityRole: "button",
|
|
4283
4419
|
accessibilityLabel,
|
|
4284
4420
|
disabled,
|
|
4285
4421
|
onPress,
|
|
4286
4422
|
style: ({ pressed }) => ({ opacity: disabled ? 0.6 : pressed ? 0.85 : 1 }),
|
|
4287
|
-
children: /* @__PURE__ */ (0,
|
|
4423
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Card, { padded: false, border: false, style, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native35.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4288
4424
|
left,
|
|
4289
|
-
/* @__PURE__ */ (0,
|
|
4425
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native35.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4290
4426
|
title,
|
|
4291
4427
|
subtitle ? subtitle : null
|
|
4292
4428
|
] }),
|
|
4293
|
-
right ? /* @__PURE__ */ (0,
|
|
4429
|
+
right ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native35.View, { style: { marginLeft: 16 }, children: right }) : null
|
|
4294
4430
|
] }) })
|
|
4295
4431
|
}
|
|
4296
4432
|
);
|
|
4297
4433
|
}
|
|
4298
4434
|
|
|
4299
4435
|
// src/studio/ui/preview-panel/SectionTitle.tsx
|
|
4300
|
-
var
|
|
4436
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
4301
4437
|
function SectionTitle({ children, marginTop }) {
|
|
4302
4438
|
const theme = useTheme();
|
|
4303
|
-
return /* @__PURE__ */ (0,
|
|
4439
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4304
4440
|
Text,
|
|
4305
4441
|
{
|
|
4306
4442
|
style: {
|
|
@@ -4319,7 +4455,7 @@ function SectionTitle({ children, marginTop }) {
|
|
|
4319
4455
|
}
|
|
4320
4456
|
|
|
4321
4457
|
// src/studio/ui/preview-panel/PreviewCustomizeSection.tsx
|
|
4322
|
-
var
|
|
4458
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
4323
4459
|
function PreviewCustomizeSection({
|
|
4324
4460
|
app,
|
|
4325
4461
|
isOwner,
|
|
@@ -4329,10 +4465,10 @@ function PreviewCustomizeSection({
|
|
|
4329
4465
|
onStartDraw
|
|
4330
4466
|
}) {
|
|
4331
4467
|
const theme = useTheme();
|
|
4332
|
-
return /* @__PURE__ */ (0,
|
|
4333
|
-
/* @__PURE__ */ (0,
|
|
4334
|
-
showProcessing ? /* @__PURE__ */ (0,
|
|
4335
|
-
|
|
4468
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
|
|
4469
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SectionTitle, { children: "Customize" }),
|
|
4470
|
+
showProcessing ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
4471
|
+
import_react_native36.View,
|
|
4336
4472
|
{
|
|
4337
4473
|
style: {
|
|
4338
4474
|
flexDirection: "row",
|
|
@@ -4345,8 +4481,8 @@ function PreviewCustomizeSection({
|
|
|
4345
4481
|
marginBottom: theme.spacing.sm
|
|
4346
4482
|
},
|
|
4347
4483
|
children: [
|
|
4348
|
-
/* @__PURE__ */ (0,
|
|
4349
|
-
|
|
4484
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4485
|
+
import_react_native36.View,
|
|
4350
4486
|
{
|
|
4351
4487
|
style: {
|
|
4352
4488
|
width: 40,
|
|
@@ -4357,17 +4493,17 @@ function PreviewCustomizeSection({
|
|
|
4357
4493
|
backgroundColor: withAlpha(theme.colors.warning, 0.1),
|
|
4358
4494
|
marginRight: theme.spacing.lg
|
|
4359
4495
|
},
|
|
4360
|
-
children: /* @__PURE__ */ (0,
|
|
4496
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native36.ActivityIndicator, { color: theme.colors.warning, size: "small" })
|
|
4361
4497
|
}
|
|
4362
4498
|
),
|
|
4363
|
-
/* @__PURE__ */ (0,
|
|
4364
|
-
/* @__PURE__ */ (0,
|
|
4365
|
-
/* @__PURE__ */ (0,
|
|
4499
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native36.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4500
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: app.status === "error" ? "Error" : "Processing" }),
|
|
4501
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: statusDescription(app.status, app.statusError) })
|
|
4366
4502
|
] })
|
|
4367
4503
|
]
|
|
4368
4504
|
}
|
|
4369
4505
|
) : null,
|
|
4370
|
-
/* @__PURE__ */ (0,
|
|
4506
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4371
4507
|
PressableCardRow,
|
|
4372
4508
|
{
|
|
4373
4509
|
accessibilityLabel: isOwner ? "Edit app" : "Remix app",
|
|
@@ -4380,8 +4516,8 @@ function PreviewCustomizeSection({
|
|
|
4380
4516
|
borderColor: withAlpha(theme.colors.primary, 0.1),
|
|
4381
4517
|
marginBottom: theme.spacing.sm
|
|
4382
4518
|
},
|
|
4383
|
-
left: /* @__PURE__ */ (0,
|
|
4384
|
-
|
|
4519
|
+
left: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4520
|
+
import_react_native36.View,
|
|
4385
4521
|
{
|
|
4386
4522
|
style: {
|
|
4387
4523
|
width: 40,
|
|
@@ -4392,15 +4528,15 @@ function PreviewCustomizeSection({
|
|
|
4392
4528
|
backgroundColor: withAlpha(theme.colors.primary, 0.1),
|
|
4393
4529
|
marginRight: theme.spacing.lg
|
|
4394
4530
|
},
|
|
4395
|
-
children: /* @__PURE__ */ (0,
|
|
4531
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(IconChat, { size: 20, colorToken: "primary" })
|
|
4396
4532
|
}
|
|
4397
4533
|
),
|
|
4398
|
-
title: /* @__PURE__ */ (0,
|
|
4399
|
-
subtitle: /* @__PURE__ */ (0,
|
|
4400
|
-
right: /* @__PURE__ */ (0,
|
|
4534
|
+
title: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: isOwner ? app.forkedFromAppId ? "Edit your Remix" : "Edit Your App" : "Remix App" }),
|
|
4535
|
+
subtitle: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: isOwner && app.forkedFromAppId ? "Make changes to your remix with chat" : shouldForkOnEdit ? "Chat to create your own copy and edit it" : "Chat to apply changes" }),
|
|
4536
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(IconChevronRight, { size: 20, colorToken: "textMuted" })
|
|
4401
4537
|
}
|
|
4402
4538
|
),
|
|
4403
|
-
isOwner && onStartDraw ? /* @__PURE__ */ (0,
|
|
4539
|
+
isOwner && onStartDraw ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4404
4540
|
PressableCardRow,
|
|
4405
4541
|
{
|
|
4406
4542
|
accessibilityLabel: "Draw changes",
|
|
@@ -4413,8 +4549,8 @@ function PreviewCustomizeSection({
|
|
|
4413
4549
|
borderColor: withAlpha(theme.colors.danger, 0.1),
|
|
4414
4550
|
marginBottom: theme.spacing.sm
|
|
4415
4551
|
},
|
|
4416
|
-
left: /* @__PURE__ */ (0,
|
|
4417
|
-
|
|
4552
|
+
left: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4553
|
+
import_react_native36.View,
|
|
4418
4554
|
{
|
|
4419
4555
|
style: {
|
|
4420
4556
|
width: 40,
|
|
@@ -4425,31 +4561,31 @@ function PreviewCustomizeSection({
|
|
|
4425
4561
|
backgroundColor: withAlpha(theme.colors.danger, 0.1),
|
|
4426
4562
|
marginRight: theme.spacing.lg
|
|
4427
4563
|
},
|
|
4428
|
-
children: /* @__PURE__ */ (0,
|
|
4564
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(IconDraw, { size: 20, colorToken: "danger" })
|
|
4429
4565
|
}
|
|
4430
4566
|
),
|
|
4431
|
-
title: /* @__PURE__ */ (0,
|
|
4432
|
-
subtitle: /* @__PURE__ */ (0,
|
|
4433
|
-
right: /* @__PURE__ */ (0,
|
|
4567
|
+
title: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Draw Changes" }),
|
|
4568
|
+
subtitle: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: "Annotate the app with drawings" }),
|
|
4569
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(IconChevronRight, { size: 20, colorToken: "textMuted" })
|
|
4434
4570
|
}
|
|
4435
4571
|
) : null
|
|
4436
4572
|
] });
|
|
4437
4573
|
}
|
|
4438
4574
|
|
|
4439
4575
|
// src/studio/ui/preview-panel/PreviewCollaborateSection.tsx
|
|
4440
|
-
var
|
|
4441
|
-
var
|
|
4576
|
+
var React31 = __toESM(require("react"));
|
|
4577
|
+
var import_react_native42 = require("react-native");
|
|
4442
4578
|
var import_lucide_react_native9 = require("lucide-react-native");
|
|
4443
4579
|
|
|
4444
4580
|
// src/components/merge-requests/MergeRequestStatusCard.tsx
|
|
4445
|
-
var
|
|
4446
|
-
var
|
|
4581
|
+
var React27 = __toESM(require("react"));
|
|
4582
|
+
var import_react_native38 = require("react-native");
|
|
4447
4583
|
var import_lucide_react_native7 = require("lucide-react-native");
|
|
4448
4584
|
|
|
4449
4585
|
// src/components/primitives/MarkdownText.tsx
|
|
4450
|
-
var
|
|
4586
|
+
var import_react_native37 = require("react-native");
|
|
4451
4587
|
var import_react_native_markdown_display = __toESM(require("react-native-markdown-display"));
|
|
4452
|
-
var
|
|
4588
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
4453
4589
|
function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
4454
4590
|
const theme = useTheme();
|
|
4455
4591
|
const isDark = theme.scheme === "dark";
|
|
@@ -4460,7 +4596,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
|
4460
4596
|
const codeTextColor = isDark ? "#FFFFFF" : theme.colors.text;
|
|
4461
4597
|
const paragraphBottom = variant === "mergeRequest" ? 8 : 6;
|
|
4462
4598
|
const baseLineHeight = variant === "mergeRequest" ? 22 : 20;
|
|
4463
|
-
return /* @__PURE__ */ (0,
|
|
4599
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_native37.View, { style, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
4464
4600
|
import_react_native_markdown_display.default,
|
|
4465
4601
|
{
|
|
4466
4602
|
style: {
|
|
@@ -4473,7 +4609,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
|
4473
4609
|
paddingHorizontal: variant === "mergeRequest" ? 6 : 4,
|
|
4474
4610
|
paddingVertical: variant === "mergeRequest" ? 2 : 0,
|
|
4475
4611
|
borderRadius: variant === "mergeRequest" ? 6 : 4,
|
|
4476
|
-
fontFamily:
|
|
4612
|
+
fontFamily: import_react_native37.Platform.OS === "ios" ? "Menlo" : "monospace",
|
|
4477
4613
|
fontSize: 13
|
|
4478
4614
|
},
|
|
4479
4615
|
code_block: {
|
|
@@ -4524,11 +4660,11 @@ function toIsoString(input) {
|
|
|
4524
4660
|
}
|
|
4525
4661
|
|
|
4526
4662
|
// src/components/merge-requests/useControlledExpansion.ts
|
|
4527
|
-
var
|
|
4663
|
+
var React26 = __toESM(require("react"));
|
|
4528
4664
|
function useControlledExpansion(props) {
|
|
4529
|
-
const [uncontrolled, setUncontrolled] =
|
|
4665
|
+
const [uncontrolled, setUncontrolled] = React26.useState(false);
|
|
4530
4666
|
const expanded = props.expanded ?? uncontrolled;
|
|
4531
|
-
const setExpanded =
|
|
4667
|
+
const setExpanded = React26.useCallback(
|
|
4532
4668
|
(next) => {
|
|
4533
4669
|
var _a;
|
|
4534
4670
|
(_a = props.onExpandedChange) == null ? void 0 : _a.call(props, next);
|
|
@@ -4540,7 +4676,7 @@ function useControlledExpansion(props) {
|
|
|
4540
4676
|
}
|
|
4541
4677
|
|
|
4542
4678
|
// src/components/merge-requests/MergeRequestStatusCard.tsx
|
|
4543
|
-
var
|
|
4679
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
4544
4680
|
function MergeRequestStatusCard({
|
|
4545
4681
|
mergeRequest,
|
|
4546
4682
|
expanded: expandedProp,
|
|
@@ -4553,8 +4689,8 @@ function MergeRequestStatusCard({
|
|
|
4553
4689
|
const isDark = theme.scheme === "dark";
|
|
4554
4690
|
const textColor = isDark ? "#FFFFFF" : "#000000";
|
|
4555
4691
|
const subTextColor = isDark ? "#A1A1AA" : "#71717A";
|
|
4556
|
-
const status =
|
|
4557
|
-
const { StatusIcon, iconColor, bgColor, statusText } =
|
|
4692
|
+
const status = React27.useMemo(() => getMergeRequestStatusDisplay(String(mergeRequest.status)), [mergeRequest.status]);
|
|
4693
|
+
const { StatusIcon, iconColor, bgColor, statusText } = React27.useMemo(() => {
|
|
4558
4694
|
switch (mergeRequest.status) {
|
|
4559
4695
|
case "approved":
|
|
4560
4696
|
case "merged":
|
|
@@ -4585,15 +4721,15 @@ function MergeRequestStatusCard({
|
|
|
4585
4721
|
const createdIso = toIsoString(mergeRequest.createdAt ?? null);
|
|
4586
4722
|
const headerTimeAgo = updatedIso ? formatTimeAgo(updatedIso) : "";
|
|
4587
4723
|
const createdTimeAgo = createdIso ? formatTimeAgo(createdIso) : "";
|
|
4588
|
-
const rotate =
|
|
4589
|
-
|
|
4590
|
-
|
|
4724
|
+
const rotate = React27.useRef(new import_react_native38.Animated.Value(expanded ? 1 : 0)).current;
|
|
4725
|
+
React27.useEffect(() => {
|
|
4726
|
+
import_react_native38.Animated.timing(rotate, {
|
|
4591
4727
|
toValue: expanded ? 1 : 0,
|
|
4592
4728
|
duration: 200,
|
|
4593
4729
|
useNativeDriver: true
|
|
4594
4730
|
}).start();
|
|
4595
4731
|
}, [expanded, rotate]);
|
|
4596
|
-
return /* @__PURE__ */ (0,
|
|
4732
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native38.Pressable, { onPress: () => setExpanded(!expanded), style: ({ pressed }) => [{ opacity: pressed ? 0.95 : 1 }], children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4597
4733
|
Card,
|
|
4598
4734
|
{
|
|
4599
4735
|
padded: false,
|
|
@@ -4606,11 +4742,11 @@ function MergeRequestStatusCard({
|
|
|
4606
4742
|
style
|
|
4607
4743
|
],
|
|
4608
4744
|
children: [
|
|
4609
|
-
/* @__PURE__ */ (0,
|
|
4610
|
-
/* @__PURE__ */ (0,
|
|
4611
|
-
/* @__PURE__ */ (0,
|
|
4612
|
-
/* @__PURE__ */ (0,
|
|
4613
|
-
/* @__PURE__ */ (0,
|
|
4745
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.lg }, children: [
|
|
4746
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native38.View, { style: { width: 40, height: 40, borderRadius: 999, alignItems: "center", justifyContent: "center", backgroundColor: bgColor }, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(StatusIcon, { size: 20, color: iconColor }) }),
|
|
4747
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4748
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
4749
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4614
4750
|
Text,
|
|
4615
4751
|
{
|
|
4616
4752
|
style: {
|
|
@@ -4624,12 +4760,12 @@ function MergeRequestStatusCard({
|
|
|
4624
4760
|
children: statusText
|
|
4625
4761
|
}
|
|
4626
4762
|
),
|
|
4627
|
-
headerTimeAgo ? /* @__PURE__ */ (0,
|
|
4763
|
+
headerTimeAgo ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 10, lineHeight: 14, marginLeft: theme.spacing.sm, color: withAlpha(theme.colors.textMuted, 0.6) }, children: headerTimeAgo }) : null
|
|
4628
4764
|
] }),
|
|
4629
|
-
/* @__PURE__ */ (0,
|
|
4765
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, numberOfLines: 1, children: mergeRequest.title ?? "Untitled merge request" })
|
|
4630
4766
|
] }),
|
|
4631
|
-
headerRight ? /* @__PURE__ */ (0,
|
|
4632
|
-
|
|
4767
|
+
headerRight ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native38.View, { children: headerRight }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4768
|
+
import_react_native38.Animated.View,
|
|
4633
4769
|
{
|
|
4634
4770
|
style: {
|
|
4635
4771
|
transform: [
|
|
@@ -4638,12 +4774,12 @@ function MergeRequestStatusCard({
|
|
|
4638
4774
|
}
|
|
4639
4775
|
]
|
|
4640
4776
|
},
|
|
4641
|
-
children: /* @__PURE__ */ (0,
|
|
4777
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native7.ChevronDown, { size: 20, color: withAlpha(theme.colors.textMuted, 0.4) })
|
|
4642
4778
|
}
|
|
4643
4779
|
)
|
|
4644
4780
|
] }),
|
|
4645
|
-
expanded ? /* @__PURE__ */ (0,
|
|
4646
|
-
/* @__PURE__ */ (0,
|
|
4781
|
+
expanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { marginTop: 16, marginLeft: 56 }, children: [
|
|
4782
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4647
4783
|
Text,
|
|
4648
4784
|
{
|
|
4649
4785
|
style: {
|
|
@@ -4657,7 +4793,7 @@ function MergeRequestStatusCard({
|
|
|
4657
4793
|
children: status.text
|
|
4658
4794
|
}
|
|
4659
4795
|
),
|
|
4660
|
-
createdTimeAgo ? /* @__PURE__ */ (0,
|
|
4796
|
+
createdTimeAgo ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4661
4797
|
Text,
|
|
4662
4798
|
{
|
|
4663
4799
|
style: {
|
|
@@ -4668,8 +4804,8 @@ function MergeRequestStatusCard({
|
|
|
4668
4804
|
children: createdTimeAgo
|
|
4669
4805
|
}
|
|
4670
4806
|
) : null,
|
|
4671
|
-
/* @__PURE__ */ (0,
|
|
4672
|
-
mergeRequest.description ? /* @__PURE__ */ (0,
|
|
4807
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 16, fontWeight: "600", color: textColor, marginBottom: 8 }, children: mergeRequest.title ?? "Untitled merge request" }),
|
|
4808
|
+
mergeRequest.description ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(MarkdownText, { markdown: mergeRequest.description, variant: "mergeRequest" }) : null
|
|
4673
4809
|
] }) : null
|
|
4674
4810
|
]
|
|
4675
4811
|
}
|
|
@@ -4677,18 +4813,18 @@ function MergeRequestStatusCard({
|
|
|
4677
4813
|
}
|
|
4678
4814
|
|
|
4679
4815
|
// src/components/merge-requests/ReviewMergeRequestCarousel.tsx
|
|
4680
|
-
var
|
|
4681
|
-
var
|
|
4816
|
+
var React30 = __toESM(require("react"));
|
|
4817
|
+
var import_react_native41 = require("react-native");
|
|
4682
4818
|
|
|
4683
4819
|
// src/components/merge-requests/ReviewMergeRequestCard.tsx
|
|
4684
|
-
var
|
|
4685
|
-
var
|
|
4820
|
+
var React29 = __toESM(require("react"));
|
|
4821
|
+
var import_react_native40 = require("react-native");
|
|
4686
4822
|
var import_lucide_react_native8 = require("lucide-react-native");
|
|
4687
4823
|
|
|
4688
4824
|
// src/components/merge-requests/ReviewMergeRequestActionButton.tsx
|
|
4689
|
-
var
|
|
4690
|
-
var
|
|
4691
|
-
var
|
|
4825
|
+
var React28 = __toESM(require("react"));
|
|
4826
|
+
var import_react_native39 = require("react-native");
|
|
4827
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
4692
4828
|
function ReviewMergeRequestActionButton({
|
|
4693
4829
|
accessibilityLabel,
|
|
4694
4830
|
backgroundColor,
|
|
@@ -4697,14 +4833,14 @@ function ReviewMergeRequestActionButton({
|
|
|
4697
4833
|
children,
|
|
4698
4834
|
iconOnly
|
|
4699
4835
|
}) {
|
|
4700
|
-
const [pressed, setPressed] =
|
|
4836
|
+
const [pressed, setPressed] = React28.useState(false);
|
|
4701
4837
|
const height = iconOnly ? 36 : 40;
|
|
4702
4838
|
const width = iconOnly ? 36 : void 0;
|
|
4703
4839
|
const paddingHorizontal = iconOnly ? 0 : 16;
|
|
4704
4840
|
const paddingVertical = iconOnly ? 0 : 8;
|
|
4705
4841
|
const opacity = disabled ? 0.5 : pressed ? 0.9 : 1;
|
|
4706
|
-
return /* @__PURE__ */ (0,
|
|
4707
|
-
|
|
4842
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4843
|
+
import_react_native39.View,
|
|
4708
4844
|
{
|
|
4709
4845
|
style: {
|
|
4710
4846
|
width,
|
|
@@ -4718,8 +4854,8 @@ function ReviewMergeRequestActionButton({
|
|
|
4718
4854
|
paddingVertical,
|
|
4719
4855
|
justifyContent: "center"
|
|
4720
4856
|
},
|
|
4721
|
-
children: /* @__PURE__ */ (0,
|
|
4722
|
-
|
|
4857
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4858
|
+
import_react_native39.Pressable,
|
|
4723
4859
|
{
|
|
4724
4860
|
accessibilityRole: "button",
|
|
4725
4861
|
accessibilityLabel,
|
|
@@ -4742,7 +4878,7 @@ function ReviewMergeRequestActionButton({
|
|
|
4742
4878
|
}
|
|
4743
4879
|
|
|
4744
4880
|
// src/components/merge-requests/ReviewMergeRequestCard.tsx
|
|
4745
|
-
var
|
|
4881
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
4746
4882
|
function ReviewMergeRequestCard({
|
|
4747
4883
|
mr,
|
|
4748
4884
|
index,
|
|
@@ -4759,14 +4895,14 @@ function ReviewMergeRequestCard({
|
|
|
4759
4895
|
onTest
|
|
4760
4896
|
}) {
|
|
4761
4897
|
const theme = useTheme();
|
|
4762
|
-
const status =
|
|
4898
|
+
const status = React29.useMemo(() => getMergeRequestStatusDisplay(mr.status), [mr.status]);
|
|
4763
4899
|
const canAct = mr.status === "open";
|
|
4764
|
-
const rotate =
|
|
4765
|
-
|
|
4766
|
-
|
|
4900
|
+
const rotate = React29.useRef(new import_react_native40.Animated.Value(isExpanded ? 1 : 0)).current;
|
|
4901
|
+
React29.useEffect(() => {
|
|
4902
|
+
import_react_native40.Animated.timing(rotate, { toValue: isExpanded ? 1 : 0, duration: 200, useNativeDriver: true }).start();
|
|
4767
4903
|
}, [isExpanded, rotate]);
|
|
4768
4904
|
const position = total > 1 ? `${index + 1}/${total}` : "Merge request";
|
|
4769
|
-
return /* @__PURE__ */ (0,
|
|
4905
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native40.Pressable, { onPress: onToggle, style: ({ pressed }) => ({ opacity: pressed ? 0.95 : 1 }), children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
4770
4906
|
Card,
|
|
4771
4907
|
{
|
|
4772
4908
|
padded: false,
|
|
@@ -4779,10 +4915,10 @@ function ReviewMergeRequestCard({
|
|
|
4779
4915
|
}
|
|
4780
4916
|
],
|
|
4781
4917
|
children: [
|
|
4782
|
-
/* @__PURE__ */ (0,
|
|
4783
|
-
/* @__PURE__ */ (0,
|
|
4784
|
-
/* @__PURE__ */ (0,
|
|
4785
|
-
/* @__PURE__ */ (0,
|
|
4918
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [
|
|
4919
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Avatar, { size: 40, uri: (creator == null ? void 0 : creator.avatar) ?? null, name: (creator == null ? void 0 : creator.name) ?? void 0 }),
|
|
4920
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4921
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4786
4922
|
Text,
|
|
4787
4923
|
{
|
|
4788
4924
|
style: { fontWeight: theme.typography.fontWeight.semibold, color: theme.colors.text, fontSize: 16, lineHeight: 20 },
|
|
@@ -4790,24 +4926,24 @@ function ReviewMergeRequestCard({
|
|
|
4790
4926
|
children: mr.title ?? "Untitled merge request"
|
|
4791
4927
|
}
|
|
4792
4928
|
),
|
|
4793
|
-
/* @__PURE__ */ (0,
|
|
4929
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16 }, numberOfLines: 1, children: [
|
|
4794
4930
|
(creator == null ? void 0 : creator.name) ?? "Loading...",
|
|
4795
4931
|
" \xB7 ",
|
|
4796
4932
|
position
|
|
4797
4933
|
] })
|
|
4798
4934
|
] }),
|
|
4799
|
-
/* @__PURE__ */ (0,
|
|
4800
|
-
|
|
4935
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4936
|
+
import_react_native40.Animated.View,
|
|
4801
4937
|
{
|
|
4802
4938
|
style: {
|
|
4803
4939
|
transform: [{ rotate: rotate.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "180deg"] }) }]
|
|
4804
4940
|
},
|
|
4805
|
-
children: /* @__PURE__ */ (0,
|
|
4941
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react_native8.ChevronDown, { size: 20, color: withAlpha(theme.colors.textMuted, 0.4) })
|
|
4806
4942
|
}
|
|
4807
4943
|
)
|
|
4808
4944
|
] }),
|
|
4809
|
-
isExpanded ? /* @__PURE__ */ (0,
|
|
4810
|
-
/* @__PURE__ */ (0,
|
|
4945
|
+
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { marginTop: 16 }, children: [
|
|
4946
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4811
4947
|
Text,
|
|
4812
4948
|
{
|
|
4813
4949
|
style: {
|
|
@@ -4821,13 +4957,13 @@ function ReviewMergeRequestCard({
|
|
|
4821
4957
|
children: status.text
|
|
4822
4958
|
}
|
|
4823
4959
|
),
|
|
4824
|
-
/* @__PURE__ */ (0,
|
|
4825
|
-
mr.description ? /* @__PURE__ */ (0,
|
|
4960
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.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..." }),
|
|
4961
|
+
mr.description ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MarkdownText, { markdown: mr.description, variant: "mergeRequest" }) : null
|
|
4826
4962
|
] }) : null,
|
|
4827
|
-
/* @__PURE__ */ (0,
|
|
4828
|
-
/* @__PURE__ */ (0,
|
|
4829
|
-
/* @__PURE__ */ (0,
|
|
4830
|
-
/* @__PURE__ */ (0,
|
|
4963
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native40.View, { style: { height: 1, backgroundColor: withAlpha(theme.colors.borderStrong, 0.5), marginTop: 12, marginBottom: 12 } }),
|
|
4964
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
4965
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", gap: 8 }, children: [
|
|
4966
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4831
4967
|
ReviewMergeRequestActionButton,
|
|
4832
4968
|
{
|
|
4833
4969
|
accessibilityLabel: "Reject",
|
|
@@ -4835,13 +4971,13 @@ function ReviewMergeRequestCard({
|
|
|
4835
4971
|
disabled: !canAct || isAnyProcessing,
|
|
4836
4972
|
onPress: onReject,
|
|
4837
4973
|
iconOnly: !isExpanded,
|
|
4838
|
-
children: /* @__PURE__ */ (0,
|
|
4839
|
-
/* @__PURE__ */ (0,
|
|
4840
|
-
isExpanded ? /* @__PURE__ */ (0,
|
|
4974
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4975
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react_native8.X, { size: 18, color: "#FFFFFF" }),
|
|
4976
|
+
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Reject" }) : null
|
|
4841
4977
|
] })
|
|
4842
4978
|
}
|
|
4843
4979
|
),
|
|
4844
|
-
/* @__PURE__ */ (0,
|
|
4980
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4845
4981
|
ReviewMergeRequestActionButton,
|
|
4846
4982
|
{
|
|
4847
4983
|
accessibilityLabel: !canAct ? "Not actionable" : isProcessing ? "Processing" : "Approve",
|
|
@@ -4849,17 +4985,17 @@ function ReviewMergeRequestCard({
|
|
|
4849
4985
|
disabled: !canAct || isAnyProcessing,
|
|
4850
4986
|
onPress: onApprove,
|
|
4851
4987
|
iconOnly: !isExpanded,
|
|
4852
|
-
children: isProcessing ? /* @__PURE__ */ (0,
|
|
4853
|
-
/* @__PURE__ */ (0,
|
|
4854
|
-
isExpanded ? /* @__PURE__ */ (0,
|
|
4855
|
-
] }) : /* @__PURE__ */ (0,
|
|
4856
|
-
/* @__PURE__ */ (0,
|
|
4857
|
-
isExpanded ? /* @__PURE__ */ (0,
|
|
4988
|
+
children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4989
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native40.ActivityIndicator, { size: "small", color: "#FFFFFF" }),
|
|
4990
|
+
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Processing" }) : null
|
|
4991
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4992
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react_native8.Check, { size: 18, color: "#FFFFFF" }),
|
|
4993
|
+
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Approve" }) : null
|
|
4858
4994
|
] })
|
|
4859
4995
|
}
|
|
4860
4996
|
)
|
|
4861
4997
|
] }),
|
|
4862
|
-
/* @__PURE__ */ (0,
|
|
4998
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4863
4999
|
ReviewMergeRequestActionButton,
|
|
4864
5000
|
{
|
|
4865
5001
|
accessibilityLabel: "Test",
|
|
@@ -4867,9 +5003,9 @@ function ReviewMergeRequestCard({
|
|
|
4867
5003
|
disabled: isBuilding || isTestingThis,
|
|
4868
5004
|
onPress: onTest,
|
|
4869
5005
|
iconOnly: !isExpanded,
|
|
4870
|
-
children: isTestingThis ? /* @__PURE__ */ (0,
|
|
4871
|
-
/* @__PURE__ */ (0,
|
|
4872
|
-
isExpanded ? /* @__PURE__ */ (0,
|
|
5006
|
+
children: isTestingThis ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native40.ActivityIndicator, { size: "small", color: "#888" }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
5007
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react_native8.Play, { size: 14, color: theme.colors.text }),
|
|
5008
|
+
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { fontSize: 13, color: theme.colors.text, fontWeight: theme.typography.fontWeight.semibold }, children: "Test" }) : null
|
|
4873
5009
|
] })
|
|
4874
5010
|
}
|
|
4875
5011
|
)
|
|
@@ -4880,7 +5016,7 @@ function ReviewMergeRequestCard({
|
|
|
4880
5016
|
}
|
|
4881
5017
|
|
|
4882
5018
|
// src/components/merge-requests/ReviewMergeRequestCarousel.tsx
|
|
4883
|
-
var
|
|
5019
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
4884
5020
|
function ReviewMergeRequestCarousel({
|
|
4885
5021
|
mergeRequests,
|
|
4886
5022
|
creatorStatsById,
|
|
@@ -4893,32 +5029,32 @@ function ReviewMergeRequestCarousel({
|
|
|
4893
5029
|
style
|
|
4894
5030
|
}) {
|
|
4895
5031
|
const theme = useTheme();
|
|
4896
|
-
const { width } = (0,
|
|
4897
|
-
const [expanded, setExpanded] =
|
|
4898
|
-
const carouselScrollX =
|
|
5032
|
+
const { width } = (0, import_react_native41.useWindowDimensions)();
|
|
5033
|
+
const [expanded, setExpanded] = React30.useState({});
|
|
5034
|
+
const carouselScrollX = React30.useRef(new import_react_native41.Animated.Value(0)).current;
|
|
4899
5035
|
const peekAmount = 24;
|
|
4900
5036
|
const gap = 16;
|
|
4901
|
-
const cardWidth =
|
|
5037
|
+
const cardWidth = React30.useMemo(() => Math.max(1, width - theme.spacing.lg * 2 - peekAmount), [peekAmount, theme.spacing.lg, width]);
|
|
4902
5038
|
const snapInterval = cardWidth + gap;
|
|
4903
5039
|
const dotColor = theme.scheme === "dark" ? "#FFFFFF" : "#000000";
|
|
4904
5040
|
if (mergeRequests.length === 0) return null;
|
|
4905
|
-
return /* @__PURE__ */ (0,
|
|
4906
|
-
/* @__PURE__ */ (0,
|
|
4907
|
-
|
|
5041
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native41.View, { style: [{ marginHorizontal: -theme.spacing.lg }, style], children: [
|
|
5042
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
5043
|
+
import_react_native41.FlatList,
|
|
4908
5044
|
{
|
|
4909
5045
|
horizontal: true,
|
|
4910
5046
|
data: mergeRequests,
|
|
4911
5047
|
keyExtractor: (mr) => mr.id,
|
|
4912
5048
|
showsHorizontalScrollIndicator: false,
|
|
4913
5049
|
contentContainerStyle: { paddingHorizontal: theme.spacing.lg, paddingVertical: theme.spacing.sm },
|
|
4914
|
-
ItemSeparatorComponent: () => /* @__PURE__ */ (0,
|
|
5050
|
+
ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native41.View, { style: { width: gap } }),
|
|
4915
5051
|
snapToAlignment: "start",
|
|
4916
5052
|
decelerationRate: "fast",
|
|
4917
5053
|
snapToInterval: snapInterval,
|
|
4918
5054
|
disableIntervalMomentum: true,
|
|
4919
5055
|
style: { paddingRight: peekAmount },
|
|
4920
|
-
ListFooterComponent: /* @__PURE__ */ (0,
|
|
4921
|
-
onScroll:
|
|
5056
|
+
ListFooterComponent: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native41.View, { style: { width: peekAmount } }),
|
|
5057
|
+
onScroll: import_react_native41.Animated.event([{ nativeEvent: { contentOffset: { x: carouselScrollX } } }], {
|
|
4922
5058
|
useNativeDriver: false
|
|
4923
5059
|
}),
|
|
4924
5060
|
scrollEventThrottle: 16,
|
|
@@ -4929,7 +5065,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4929
5065
|
const isProcessing = Boolean(processingMrId && processingMrId === item.id);
|
|
4930
5066
|
const isAnyProcessing = Boolean(processingMrId);
|
|
4931
5067
|
const isTestingThis = Boolean(testingMrId && testingMrId === item.id);
|
|
4932
|
-
return /* @__PURE__ */ (0,
|
|
5068
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native41.View, { style: { width: cardWidth }, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
4933
5069
|
ReviewMergeRequestCard,
|
|
4934
5070
|
{
|
|
4935
5071
|
mr: item,
|
|
@@ -4950,7 +5086,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4950
5086
|
}
|
|
4951
5087
|
}
|
|
4952
5088
|
),
|
|
4953
|
-
mergeRequests.length >= 1 ? /* @__PURE__ */ (0,
|
|
5089
|
+
mergeRequests.length >= 1 ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native41.View, { style: { flexDirection: "row", justifyContent: "center", columnGap: 8, marginTop: theme.spacing.md }, children: mergeRequests.map((mr, index) => {
|
|
4954
5090
|
const inputRange = [(index - 1) * snapInterval, index * snapInterval, (index + 1) * snapInterval];
|
|
4955
5091
|
const scale = carouselScrollX.interpolate({
|
|
4956
5092
|
inputRange,
|
|
@@ -4962,8 +5098,8 @@ function ReviewMergeRequestCarousel({
|
|
|
4962
5098
|
outputRange: [0.4, 1, 0.4],
|
|
4963
5099
|
extrapolate: "clamp"
|
|
4964
5100
|
});
|
|
4965
|
-
return /* @__PURE__ */ (0,
|
|
4966
|
-
|
|
5101
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
5102
|
+
import_react_native41.Animated.View,
|
|
4967
5103
|
{
|
|
4968
5104
|
style: {
|
|
4969
5105
|
width: 8,
|
|
@@ -4981,7 +5117,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4981
5117
|
}
|
|
4982
5118
|
|
|
4983
5119
|
// src/studio/ui/preview-panel/PreviewCollaborateSection.tsx
|
|
4984
|
-
var
|
|
5120
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
4985
5121
|
function PreviewCollaborateSection({
|
|
4986
5122
|
canSubmitMergeRequest,
|
|
4987
5123
|
incomingMergeRequests,
|
|
@@ -4997,13 +5133,13 @@ function PreviewCollaborateSection({
|
|
|
4997
5133
|
onTestMr
|
|
4998
5134
|
}) {
|
|
4999
5135
|
const theme = useTheme();
|
|
5000
|
-
const [submittingMr, setSubmittingMr] =
|
|
5136
|
+
const [submittingMr, setSubmittingMr] = React31.useState(false);
|
|
5001
5137
|
const hasSection = canSubmitMergeRequest || incomingMergeRequests.length > 0 || outgoingMergeRequests.length > 0;
|
|
5002
5138
|
if (!hasSection) return null;
|
|
5003
5139
|
const showActionsSubtitle = canSubmitMergeRequest && onSubmitMergeRequest || onTestMr && incomingMergeRequests.length > 0;
|
|
5004
|
-
return /* @__PURE__ */ (0,
|
|
5005
|
-
/* @__PURE__ */ (0,
|
|
5006
|
-
showActionsSubtitle ? /* @__PURE__ */ (0,
|
|
5140
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_jsx_runtime44.Fragment, { children: [
|
|
5141
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(SectionTitle, { marginTop: theme.spacing.xl, children: "Collaborate" }),
|
|
5142
|
+
showActionsSubtitle ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5007
5143
|
Text,
|
|
5008
5144
|
{
|
|
5009
5145
|
style: {
|
|
@@ -5018,13 +5154,13 @@ function PreviewCollaborateSection({
|
|
|
5018
5154
|
children: "Actions"
|
|
5019
5155
|
}
|
|
5020
5156
|
) : null,
|
|
5021
|
-
canSubmitMergeRequest && onSubmitMergeRequest ? /* @__PURE__ */ (0,
|
|
5157
|
+
canSubmitMergeRequest && onSubmitMergeRequest ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5022
5158
|
PressableCardRow,
|
|
5023
5159
|
{
|
|
5024
5160
|
accessibilityLabel: "Submit merge request",
|
|
5025
5161
|
disabled: submittingMr,
|
|
5026
5162
|
onPress: () => {
|
|
5027
|
-
|
|
5163
|
+
import_react_native42.Alert.alert(
|
|
5028
5164
|
"Submit Merge Request",
|
|
5029
5165
|
"Are you sure you want to submit your changes to the original app?",
|
|
5030
5166
|
[
|
|
@@ -5049,8 +5185,8 @@ function PreviewCollaborateSection({
|
|
|
5049
5185
|
borderColor: withAlpha("#03DAC6", 0.2),
|
|
5050
5186
|
marginBottom: theme.spacing.sm
|
|
5051
5187
|
},
|
|
5052
|
-
left: /* @__PURE__ */ (0,
|
|
5053
|
-
|
|
5188
|
+
left: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5189
|
+
import_react_native42.View,
|
|
5054
5190
|
{
|
|
5055
5191
|
style: {
|
|
5056
5192
|
width: 40,
|
|
@@ -5061,15 +5197,15 @@ function PreviewCollaborateSection({
|
|
|
5061
5197
|
backgroundColor: withAlpha("#03DAC6", 0.1),
|
|
5062
5198
|
marginRight: theme.spacing.lg
|
|
5063
5199
|
},
|
|
5064
|
-
children: submittingMr ? /* @__PURE__ */ (0,
|
|
5200
|
+
children: submittingMr ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native42.ActivityIndicator, { color: "#03DAC6", size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(MergeIcon, { width: 20, height: 20, color: "#03DAC6" })
|
|
5065
5201
|
}
|
|
5066
5202
|
),
|
|
5067
|
-
title: /* @__PURE__ */ (0,
|
|
5068
|
-
subtitle: /* @__PURE__ */ (0,
|
|
5069
|
-
right: /* @__PURE__ */ (0,
|
|
5203
|
+
title: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Submit your new changes" }),
|
|
5204
|
+
subtitle: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: "Ask to merge this remix to the original app" }),
|
|
5205
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react_native9.Send, { size: 16, color: "#03DAC6" })
|
|
5070
5206
|
}
|
|
5071
5207
|
) : null,
|
|
5072
|
-
onTestMr && incomingMergeRequests.length > 0 ? /* @__PURE__ */ (0,
|
|
5208
|
+
onTestMr && incomingMergeRequests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5073
5209
|
ReviewMergeRequestCarousel,
|
|
5074
5210
|
{
|
|
5075
5211
|
mergeRequests: incomingMergeRequests,
|
|
@@ -5082,8 +5218,8 @@ function PreviewCollaborateSection({
|
|
|
5082
5218
|
onTest: (mr) => onTestMr ? onTestMr(mr) : void 0
|
|
5083
5219
|
}
|
|
5084
5220
|
) : null,
|
|
5085
|
-
outgoingMergeRequests.length > 0 ? /* @__PURE__ */ (0,
|
|
5086
|
-
/* @__PURE__ */ (0,
|
|
5221
|
+
outgoingMergeRequests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_jsx_runtime44.Fragment, { children: [
|
|
5222
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5087
5223
|
Text,
|
|
5088
5224
|
{
|
|
5089
5225
|
style: {
|
|
@@ -5099,13 +5235,13 @@ function PreviewCollaborateSection({
|
|
|
5099
5235
|
children: "History"
|
|
5100
5236
|
}
|
|
5101
5237
|
),
|
|
5102
|
-
outgoingMergeRequests.map((mr) => /* @__PURE__ */ (0,
|
|
5238
|
+
outgoingMergeRequests.map((mr) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native42.View, { style: { marginBottom: theme.spacing.sm }, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(MergeRequestStatusCard, { mergeRequest: toMergeRequestSummary(mr) }) }, mr.id))
|
|
5103
5239
|
] }) : null
|
|
5104
5240
|
] });
|
|
5105
5241
|
}
|
|
5106
5242
|
|
|
5107
5243
|
// src/studio/ui/preview-panel/usePreviewPanelData.ts
|
|
5108
|
-
var
|
|
5244
|
+
var React33 = __toESM(require("react"));
|
|
5109
5245
|
|
|
5110
5246
|
// src/data/apps/images/remote.ts
|
|
5111
5247
|
var AppImagesRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -5156,7 +5292,7 @@ var AppImagesRepositoryImpl = class extends BaseRepository {
|
|
|
5156
5292
|
var appImagesRepository = new AppImagesRepositoryImpl(appImagesRemoteDataSource);
|
|
5157
5293
|
|
|
5158
5294
|
// src/studio/hooks/useAppStats.ts
|
|
5159
|
-
var
|
|
5295
|
+
var React32 = __toESM(require("react"));
|
|
5160
5296
|
var Haptics2 = __toESM(require("expo-haptics"));
|
|
5161
5297
|
|
|
5162
5298
|
// src/data/likes/remote.ts
|
|
@@ -5225,34 +5361,34 @@ function useAppStats({
|
|
|
5225
5361
|
initialIsLiked = false,
|
|
5226
5362
|
onOpenComments
|
|
5227
5363
|
}) {
|
|
5228
|
-
const [likeCount, setLikeCount] =
|
|
5229
|
-
const [commentCount, setCommentCount] =
|
|
5230
|
-
const [forkCount, setForkCount] =
|
|
5231
|
-
const [isLiked, setIsLiked] =
|
|
5232
|
-
const didMutateRef =
|
|
5233
|
-
const lastAppIdRef =
|
|
5234
|
-
|
|
5364
|
+
const [likeCount, setLikeCount] = React32.useState(initialLikes);
|
|
5365
|
+
const [commentCount, setCommentCount] = React32.useState(initialComments);
|
|
5366
|
+
const [forkCount, setForkCount] = React32.useState(initialForks);
|
|
5367
|
+
const [isLiked, setIsLiked] = React32.useState(initialIsLiked);
|
|
5368
|
+
const didMutateRef = React32.useRef(false);
|
|
5369
|
+
const lastAppIdRef = React32.useRef("");
|
|
5370
|
+
React32.useEffect(() => {
|
|
5235
5371
|
if (lastAppIdRef.current === appId) return;
|
|
5236
5372
|
lastAppIdRef.current = appId;
|
|
5237
5373
|
didMutateRef.current = false;
|
|
5238
5374
|
}, [appId]);
|
|
5239
|
-
|
|
5375
|
+
React32.useEffect(() => {
|
|
5240
5376
|
if (didMutateRef.current) return;
|
|
5241
5377
|
setLikeCount(initialLikes);
|
|
5242
5378
|
}, [appId, initialLikes]);
|
|
5243
|
-
|
|
5379
|
+
React32.useEffect(() => {
|
|
5244
5380
|
if (didMutateRef.current) return;
|
|
5245
5381
|
setCommentCount(initialComments);
|
|
5246
5382
|
}, [appId, initialComments]);
|
|
5247
|
-
|
|
5383
|
+
React32.useEffect(() => {
|
|
5248
5384
|
if (didMutateRef.current) return;
|
|
5249
5385
|
setForkCount(initialForks);
|
|
5250
5386
|
}, [appId, initialForks]);
|
|
5251
|
-
|
|
5387
|
+
React32.useEffect(() => {
|
|
5252
5388
|
if (didMutateRef.current) return;
|
|
5253
5389
|
setIsLiked(initialIsLiked);
|
|
5254
5390
|
}, [appId, initialIsLiked]);
|
|
5255
|
-
const handleLike =
|
|
5391
|
+
const handleLike = React32.useCallback(async () => {
|
|
5256
5392
|
var _a, _b;
|
|
5257
5393
|
if (!appId) return;
|
|
5258
5394
|
didMutateRef.current = true;
|
|
@@ -5276,7 +5412,7 @@ function useAppStats({
|
|
|
5276
5412
|
setLikeCount((prev) => Math.max(0, prev + (newIsLiked ? -1 : 1)));
|
|
5277
5413
|
}
|
|
5278
5414
|
}, [appId, isLiked, likeCount]);
|
|
5279
|
-
const handleOpenComments =
|
|
5415
|
+
const handleOpenComments = React32.useCallback(() => {
|
|
5280
5416
|
if (!appId) return;
|
|
5281
5417
|
try {
|
|
5282
5418
|
void Haptics2.impactAsync(Haptics2.ImpactFeedbackStyle.Light);
|
|
@@ -5291,11 +5427,11 @@ function useAppStats({
|
|
|
5291
5427
|
var LIKE_DEBUG_PREFIX = "[COMERGE_LIKE_DEBUG]";
|
|
5292
5428
|
function usePreviewPanelData(params) {
|
|
5293
5429
|
const { app, isOwner, outgoingMergeRequests, onOpenComments, commentCountOverride } = params;
|
|
5294
|
-
const [imageUrl, setImageUrl] =
|
|
5295
|
-
const [imageLoaded, setImageLoaded] =
|
|
5296
|
-
const [insights, setInsights] =
|
|
5297
|
-
const [creator, setCreator] =
|
|
5298
|
-
|
|
5430
|
+
const [imageUrl, setImageUrl] = React33.useState(null);
|
|
5431
|
+
const [imageLoaded, setImageLoaded] = React33.useState(false);
|
|
5432
|
+
const [insights, setInsights] = React33.useState({ likes: 0, comments: 0, forks: 0, downloads: 0 });
|
|
5433
|
+
const [creator, setCreator] = React33.useState(null);
|
|
5434
|
+
React33.useEffect(() => {
|
|
5299
5435
|
if (!(app == null ? void 0 : app.id)) return;
|
|
5300
5436
|
let cancelled = false;
|
|
5301
5437
|
(async () => {
|
|
@@ -5310,7 +5446,7 @@ function usePreviewPanelData(params) {
|
|
|
5310
5446
|
cancelled = true;
|
|
5311
5447
|
};
|
|
5312
5448
|
}, [app == null ? void 0 : app.id]);
|
|
5313
|
-
|
|
5449
|
+
React33.useEffect(() => {
|
|
5314
5450
|
if (!(app == null ? void 0 : app.createdBy)) return;
|
|
5315
5451
|
let cancelled = false;
|
|
5316
5452
|
(async () => {
|
|
@@ -5326,10 +5462,10 @@ function usePreviewPanelData(params) {
|
|
|
5326
5462
|
cancelled = true;
|
|
5327
5463
|
};
|
|
5328
5464
|
}, [app == null ? void 0 : app.createdBy]);
|
|
5329
|
-
|
|
5465
|
+
React33.useEffect(() => {
|
|
5330
5466
|
setImageLoaded(false);
|
|
5331
5467
|
}, [app == null ? void 0 : app.id]);
|
|
5332
|
-
|
|
5468
|
+
React33.useEffect(() => {
|
|
5333
5469
|
if (!(app == null ? void 0 : app.id)) return;
|
|
5334
5470
|
let cancelled = false;
|
|
5335
5471
|
(async () => {
|
|
@@ -5354,7 +5490,7 @@ function usePreviewPanelData(params) {
|
|
|
5354
5490
|
cancelled = true;
|
|
5355
5491
|
};
|
|
5356
5492
|
}, [app == null ? void 0 : app.id]);
|
|
5357
|
-
|
|
5493
|
+
React33.useEffect(() => {
|
|
5358
5494
|
if (!(app == null ? void 0 : app.id)) return;
|
|
5359
5495
|
log.debug(
|
|
5360
5496
|
`${LIKE_DEBUG_PREFIX} usePreviewPanelData.appChanged appId=${app.id} app.isLiked=${String(app.isLiked)}`
|
|
@@ -5368,7 +5504,7 @@ function usePreviewPanelData(params) {
|
|
|
5368
5504
|
initialIsLiked: Boolean(app == null ? void 0 : app.isLiked),
|
|
5369
5505
|
onOpenComments
|
|
5370
5506
|
});
|
|
5371
|
-
const canSubmitMergeRequest =
|
|
5507
|
+
const canSubmitMergeRequest = React33.useMemo(() => {
|
|
5372
5508
|
if (!isOwner) return false;
|
|
5373
5509
|
if (!app) return false;
|
|
5374
5510
|
if (!app.forkedFromAppId) return false;
|
|
@@ -5390,7 +5526,7 @@ function usePreviewPanelData(params) {
|
|
|
5390
5526
|
}
|
|
5391
5527
|
|
|
5392
5528
|
// src/studio/ui/PreviewPanel.tsx
|
|
5393
|
-
var
|
|
5529
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
5394
5530
|
function PreviewPanel({
|
|
5395
5531
|
app,
|
|
5396
5532
|
loading,
|
|
@@ -5421,16 +5557,16 @@ function PreviewPanel({
|
|
|
5421
5557
|
onOpenComments,
|
|
5422
5558
|
commentCountOverride
|
|
5423
5559
|
});
|
|
5424
|
-
const header = /* @__PURE__ */ (0,
|
|
5560
|
+
const header = /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(PreviewPanelHeader, { isOwner, onClose, onNavigateHome, onGoToChat });
|
|
5425
5561
|
if (loading || !app) {
|
|
5426
|
-
return /* @__PURE__ */ (0,
|
|
5427
|
-
/* @__PURE__ */ (0,
|
|
5428
|
-
/* @__PURE__ */ (0,
|
|
5429
|
-
/* @__PURE__ */ (0,
|
|
5562
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(PreviewPage, { header, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_react_native43.View, { style: { flex: 1, justifyContent: "center", alignItems: "center", padding: 24 }, children: [
|
|
5563
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native43.ActivityIndicator, {}),
|
|
5564
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native43.View, { style: { height: 12 } }),
|
|
5565
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Text, { variant: "bodyMuted", children: "Loading app\u2026" })
|
|
5430
5566
|
] }) });
|
|
5431
5567
|
}
|
|
5432
|
-
return /* @__PURE__ */ (0,
|
|
5433
|
-
/* @__PURE__ */ (0,
|
|
5568
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(PreviewPage, { header, children: [
|
|
5569
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5434
5570
|
PreviewHeroSection,
|
|
5435
5571
|
{
|
|
5436
5572
|
appStatus: app.status,
|
|
@@ -5448,8 +5584,8 @@ function PreviewPanel({
|
|
|
5448
5584
|
}
|
|
5449
5585
|
}
|
|
5450
5586
|
),
|
|
5451
|
-
/* @__PURE__ */ (0,
|
|
5452
|
-
/* @__PURE__ */ (0,
|
|
5587
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(PreviewMetaSection, { app, isOwner, creator, downloadsCount: insights.downloads }),
|
|
5588
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5453
5589
|
PreviewCustomizeSection,
|
|
5454
5590
|
{
|
|
5455
5591
|
app,
|
|
@@ -5460,7 +5596,7 @@ function PreviewPanel({
|
|
|
5460
5596
|
onStartDraw
|
|
5461
5597
|
}
|
|
5462
5598
|
),
|
|
5463
|
-
/* @__PURE__ */ (0,
|
|
5599
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5464
5600
|
PreviewCollaborateSection,
|
|
5465
5601
|
{
|
|
5466
5602
|
canSubmitMergeRequest,
|
|
@@ -5481,23 +5617,23 @@ function PreviewPanel({
|
|
|
5481
5617
|
}
|
|
5482
5618
|
|
|
5483
5619
|
// src/studio/ui/ChatPanel.tsx
|
|
5484
|
-
var
|
|
5485
|
-
var
|
|
5620
|
+
var React38 = __toESM(require("react"));
|
|
5621
|
+
var import_react_native51 = require("react-native");
|
|
5486
5622
|
|
|
5487
5623
|
// src/components/chat/ChatPage.tsx
|
|
5488
|
-
var
|
|
5489
|
-
var
|
|
5624
|
+
var React36 = __toESM(require("react"));
|
|
5625
|
+
var import_react_native47 = require("react-native");
|
|
5490
5626
|
var import_react_native_safe_area_context4 = require("react-native-safe-area-context");
|
|
5491
5627
|
|
|
5492
5628
|
// src/components/chat/ChatMessageList.tsx
|
|
5493
|
-
var
|
|
5494
|
-
var
|
|
5629
|
+
var React35 = __toESM(require("react"));
|
|
5630
|
+
var import_react_native46 = require("react-native");
|
|
5495
5631
|
var import_bottom_sheet5 = require("@gorhom/bottom-sheet");
|
|
5496
5632
|
|
|
5497
5633
|
// src/components/chat/ChatMessageBubble.tsx
|
|
5498
|
-
var
|
|
5634
|
+
var import_react_native44 = require("react-native");
|
|
5499
5635
|
var import_lucide_react_native10 = require("lucide-react-native");
|
|
5500
|
-
var
|
|
5636
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
5501
5637
|
function ChatMessageBubble({ message, renderContent, style }) {
|
|
5502
5638
|
var _a, _b;
|
|
5503
5639
|
const theme = useTheme();
|
|
@@ -5511,7 +5647,7 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5511
5647
|
const bubbleVariant = isHuman ? "surface" : "surfaceRaised";
|
|
5512
5648
|
const cornerStyle = isHuman ? { borderTopRightRadius: 0 } : { borderTopLeftRadius: 0 };
|
|
5513
5649
|
const bodyColor = metaStatus === "success" ? theme.colors.success : metaStatus === "error" ? theme.colors.danger : void 0;
|
|
5514
|
-
return /* @__PURE__ */ (0,
|
|
5650
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native44.View, { style: [align, style], children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
5515
5651
|
Surface,
|
|
5516
5652
|
{
|
|
5517
5653
|
variant: bubbleVariant,
|
|
@@ -5526,34 +5662,34 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5526
5662
|
},
|
|
5527
5663
|
cornerStyle
|
|
5528
5664
|
],
|
|
5529
|
-
children: /* @__PURE__ */ (0,
|
|
5530
|
-
isMergeCompleted ? /* @__PURE__ */ (0,
|
|
5531
|
-
isMergeApproved ? /* @__PURE__ */ (0,
|
|
5532
|
-
/* @__PURE__ */ (0,
|
|
5665
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_react_native44.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5666
|
+
isMergeCompleted ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react_native10.CheckCheck, { size: 16, color: theme.colors.success, style: { marginRight: theme.spacing.sm } }) : null,
|
|
5667
|
+
isMergeApproved ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react_native10.GitMerge, { size: 16, color: theme.colors.text, style: { marginRight: theme.spacing.sm } }) : null,
|
|
5668
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native44.View, { style: { flexShrink: 1, minWidth: 0 }, children: renderContent ? renderContent(message) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(MarkdownText, { markdown: message.content, variant: "chat", bodyColor }) })
|
|
5533
5669
|
] })
|
|
5534
5670
|
}
|
|
5535
5671
|
) });
|
|
5536
5672
|
}
|
|
5537
5673
|
|
|
5538
5674
|
// src/components/chat/TypingIndicator.tsx
|
|
5539
|
-
var
|
|
5540
|
-
var
|
|
5541
|
-
var
|
|
5675
|
+
var React34 = __toESM(require("react"));
|
|
5676
|
+
var import_react_native45 = require("react-native");
|
|
5677
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
5542
5678
|
function TypingIndicator({ style }) {
|
|
5543
5679
|
const theme = useTheme();
|
|
5544
5680
|
const dotColor = theme.colors.textSubtle;
|
|
5545
|
-
const anims =
|
|
5546
|
-
() => [new
|
|
5681
|
+
const anims = React34.useMemo(
|
|
5682
|
+
() => [new import_react_native45.Animated.Value(0.3), new import_react_native45.Animated.Value(0.3), new import_react_native45.Animated.Value(0.3)],
|
|
5547
5683
|
[]
|
|
5548
5684
|
);
|
|
5549
|
-
|
|
5685
|
+
React34.useEffect(() => {
|
|
5550
5686
|
const loops = [];
|
|
5551
5687
|
anims.forEach((a, idx) => {
|
|
5552
|
-
const seq =
|
|
5553
|
-
|
|
5554
|
-
|
|
5688
|
+
const seq = import_react_native45.Animated.sequence([
|
|
5689
|
+
import_react_native45.Animated.timing(a, { toValue: 1, duration: 420, useNativeDriver: true, delay: idx * 140 }),
|
|
5690
|
+
import_react_native45.Animated.timing(a, { toValue: 0.3, duration: 420, useNativeDriver: true })
|
|
5555
5691
|
]);
|
|
5556
|
-
const loop =
|
|
5692
|
+
const loop = import_react_native45.Animated.loop(seq);
|
|
5557
5693
|
loops.push(loop);
|
|
5558
5694
|
loop.start();
|
|
5559
5695
|
});
|
|
@@ -5561,8 +5697,8 @@ function TypingIndicator({ style }) {
|
|
|
5561
5697
|
loops.forEach((l) => l.stop());
|
|
5562
5698
|
};
|
|
5563
5699
|
}, [anims]);
|
|
5564
|
-
return /* @__PURE__ */ (0,
|
|
5565
|
-
|
|
5700
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native45.View, { style: [{ flexDirection: "row", alignItems: "center" }, style], children: anims.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
5701
|
+
import_react_native45.Animated.View,
|
|
5566
5702
|
{
|
|
5567
5703
|
style: {
|
|
5568
5704
|
width: 8,
|
|
@@ -5571,7 +5707,7 @@ function TypingIndicator({ style }) {
|
|
|
5571
5707
|
marginHorizontal: 3,
|
|
5572
5708
|
backgroundColor: dotColor,
|
|
5573
5709
|
opacity: a,
|
|
5574
|
-
transform: [{ translateY:
|
|
5710
|
+
transform: [{ translateY: import_react_native45.Animated.multiply(import_react_native45.Animated.subtract(a, 0.3), 2) }]
|
|
5575
5711
|
}
|
|
5576
5712
|
},
|
|
5577
5713
|
i
|
|
@@ -5579,8 +5715,8 @@ function TypingIndicator({ style }) {
|
|
|
5579
5715
|
}
|
|
5580
5716
|
|
|
5581
5717
|
// src/components/chat/ChatMessageList.tsx
|
|
5582
|
-
var
|
|
5583
|
-
var ChatMessageList =
|
|
5718
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
5719
|
+
var ChatMessageList = React35.forwardRef(
|
|
5584
5720
|
({
|
|
5585
5721
|
messages,
|
|
5586
5722
|
showTypingIndicator = false,
|
|
@@ -5591,23 +5727,23 @@ var ChatMessageList = React33.forwardRef(
|
|
|
5591
5727
|
nearBottomThreshold = 200
|
|
5592
5728
|
}, ref) => {
|
|
5593
5729
|
const theme = useTheme();
|
|
5594
|
-
const listRef =
|
|
5595
|
-
const nearBottomRef =
|
|
5596
|
-
const initialScrollDoneRef =
|
|
5597
|
-
const lastMessageIdRef =
|
|
5598
|
-
const
|
|
5730
|
+
const listRef = React35.useRef(null);
|
|
5731
|
+
const nearBottomRef = React35.useRef(true);
|
|
5732
|
+
const initialScrollDoneRef = React35.useRef(false);
|
|
5733
|
+
const lastMessageIdRef = React35.useRef(null);
|
|
5734
|
+
const data = React35.useMemo(() => {
|
|
5735
|
+
return [...messages].reverse();
|
|
5736
|
+
}, [messages]);
|
|
5737
|
+
const scrollToBottom = React35.useCallback((options) => {
|
|
5599
5738
|
var _a;
|
|
5600
5739
|
const animated = (options == null ? void 0 : options.animated) ?? true;
|
|
5601
|
-
(_a = listRef.current) == null ? void 0 : _a.
|
|
5740
|
+
(_a = listRef.current) == null ? void 0 : _a.scrollToOffset({ offset: 0, animated });
|
|
5602
5741
|
}, []);
|
|
5603
|
-
|
|
5604
|
-
const handleScroll =
|
|
5742
|
+
React35.useImperativeHandle(ref, () => ({ scrollToBottom }), [scrollToBottom]);
|
|
5743
|
+
const handleScroll = React35.useCallback(
|
|
5605
5744
|
(e) => {
|
|
5606
5745
|
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
|
-
);
|
|
5746
|
+
const distanceFromBottom = Math.max(contentOffset.y - Math.max(bottomInset, 0), 0);
|
|
5611
5747
|
const isNear = distanceFromBottom <= nearBottomThreshold;
|
|
5612
5748
|
if (nearBottomRef.current !== isNear) {
|
|
5613
5749
|
nearBottomRef.current = isNear;
|
|
@@ -5616,16 +5752,7 @@ var ChatMessageList = React33.forwardRef(
|
|
|
5616
5752
|
},
|
|
5617
5753
|
[bottomInset, nearBottomThreshold, onNearBottomChange]
|
|
5618
5754
|
);
|
|
5619
|
-
|
|
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
|
-
React33.useEffect(() => {
|
|
5755
|
+
React35.useEffect(() => {
|
|
5629
5756
|
if (!initialScrollDoneRef.current) return;
|
|
5630
5757
|
const lastId = messages.length > 0 ? messages[messages.length - 1].id : null;
|
|
5631
5758
|
const prevLastId = lastMessageIdRef.current;
|
|
@@ -5635,42 +5762,44 @@ var ChatMessageList = React33.forwardRef(
|
|
|
5635
5762
|
const id = requestAnimationFrame(() => scrollToBottom({ animated: true }));
|
|
5636
5763
|
return () => cancelAnimationFrame(id);
|
|
5637
5764
|
}, [messages, scrollToBottom]);
|
|
5638
|
-
|
|
5765
|
+
React35.useEffect(() => {
|
|
5639
5766
|
if (showTypingIndicator && nearBottomRef.current) {
|
|
5640
5767
|
const id = requestAnimationFrame(() => scrollToBottom({ animated: true }));
|
|
5641
5768
|
return () => cancelAnimationFrame(id);
|
|
5642
5769
|
}
|
|
5643
5770
|
return void 0;
|
|
5644
5771
|
}, [showTypingIndicator, scrollToBottom]);
|
|
5645
|
-
|
|
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
|
-
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
5772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
5652
5773
|
import_bottom_sheet5.BottomSheetFlatList,
|
|
5653
5774
|
{
|
|
5654
5775
|
ref: listRef,
|
|
5655
|
-
|
|
5776
|
+
inverted: true,
|
|
5777
|
+
data,
|
|
5656
5778
|
keyExtractor: (m) => m.id,
|
|
5657
|
-
keyboardDismissMode: import_react_native44.Platform.OS === "ios" ? "interactive" : "on-drag",
|
|
5658
5779
|
keyboardShouldPersistTaps: "handled",
|
|
5659
5780
|
onScroll: handleScroll,
|
|
5660
5781
|
scrollEventThrottle: 16,
|
|
5661
5782
|
showsVerticalScrollIndicator: false,
|
|
5783
|
+
onContentSizeChange: () => {
|
|
5784
|
+
if (initialScrollDoneRef.current) return;
|
|
5785
|
+
initialScrollDoneRef.current = true;
|
|
5786
|
+
lastMessageIdRef.current = messages.length > 0 ? messages[messages.length - 1].id : null;
|
|
5787
|
+
nearBottomRef.current = true;
|
|
5788
|
+
onNearBottomChange == null ? void 0 : onNearBottomChange(true);
|
|
5789
|
+
requestAnimationFrame(() => scrollToBottom({ animated: false }));
|
|
5790
|
+
},
|
|
5662
5791
|
contentContainerStyle: [
|
|
5663
5792
|
{
|
|
5664
5793
|
paddingHorizontal: theme.spacing.lg,
|
|
5665
|
-
|
|
5666
|
-
paddingBottom: theme.spacing.sm
|
|
5794
|
+
paddingVertical: theme.spacing.sm
|
|
5667
5795
|
},
|
|
5668
5796
|
contentStyle
|
|
5669
5797
|
],
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5798
|
+
ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native46.View, { style: { height: theme.spacing.sm } }),
|
|
5799
|
+
renderItem: ({ item }) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ChatMessageBubble, { message: item, renderContent: renderMessageContent }),
|
|
5800
|
+
ListHeaderComponent: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native46.View, { children: [
|
|
5801
|
+
showTypingIndicator ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native46.View, { style: { marginTop: theme.spacing.sm, alignSelf: "flex-start", paddingHorizontal: theme.spacing.lg }, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TypingIndicator, {}) }) : null,
|
|
5802
|
+
bottomInset > 0 ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native46.View, { style: { height: bottomInset } }) : null
|
|
5674
5803
|
] })
|
|
5675
5804
|
}
|
|
5676
5805
|
);
|
|
@@ -5679,7 +5808,7 @@ var ChatMessageList = React33.forwardRef(
|
|
|
5679
5808
|
ChatMessageList.displayName = "ChatMessageList";
|
|
5680
5809
|
|
|
5681
5810
|
// src/components/chat/ChatPage.tsx
|
|
5682
|
-
var
|
|
5811
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
5683
5812
|
function ChatPage({
|
|
5684
5813
|
header,
|
|
5685
5814
|
messages,
|
|
@@ -5689,44 +5818,45 @@ function ChatPage({
|
|
|
5689
5818
|
composer,
|
|
5690
5819
|
overlay,
|
|
5691
5820
|
style,
|
|
5821
|
+
composerHorizontalPadding,
|
|
5692
5822
|
onNearBottomChange,
|
|
5693
5823
|
listRef
|
|
5694
5824
|
}) {
|
|
5695
5825
|
const theme = useTheme();
|
|
5696
5826
|
const insets = (0, import_react_native_safe_area_context4.useSafeAreaInsets)();
|
|
5697
|
-
const [composerHeight, setComposerHeight] =
|
|
5698
|
-
const [keyboardVisible, setKeyboardVisible] =
|
|
5699
|
-
|
|
5700
|
-
if (
|
|
5701
|
-
const show =
|
|
5702
|
-
const hide =
|
|
5827
|
+
const [composerHeight, setComposerHeight] = React36.useState(0);
|
|
5828
|
+
const [keyboardVisible, setKeyboardVisible] = React36.useState(false);
|
|
5829
|
+
React36.useEffect(() => {
|
|
5830
|
+
if (import_react_native47.Platform.OS !== "ios") return;
|
|
5831
|
+
const show = import_react_native47.Keyboard.addListener("keyboardWillShow", () => setKeyboardVisible(true));
|
|
5832
|
+
const hide = import_react_native47.Keyboard.addListener("keyboardWillHide", () => setKeyboardVisible(false));
|
|
5703
5833
|
return () => {
|
|
5704
5834
|
show.remove();
|
|
5705
5835
|
hide.remove();
|
|
5706
5836
|
};
|
|
5707
5837
|
}, []);
|
|
5708
|
-
const footerBottomPadding =
|
|
5838
|
+
const footerBottomPadding = import_react_native47.Platform.OS === "ios" ? keyboardVisible ? 0 : insets.bottom : insets.bottom + 10;
|
|
5709
5839
|
const overlayBottom = composerHeight + footerBottomPadding + theme.spacing.lg;
|
|
5710
5840
|
const bottomInset = composerHeight + footerBottomPadding + theme.spacing.xl;
|
|
5711
|
-
const resolvedOverlay =
|
|
5841
|
+
const resolvedOverlay = React36.useMemo(() => {
|
|
5712
5842
|
var _a;
|
|
5713
5843
|
if (!overlay) return null;
|
|
5714
|
-
if (!
|
|
5844
|
+
if (!React36.isValidElement(overlay)) return overlay;
|
|
5715
5845
|
const prevStyle = (_a = overlay.props) == null ? void 0 : _a.style;
|
|
5716
|
-
return
|
|
5846
|
+
return React36.cloneElement(overlay, {
|
|
5717
5847
|
style: [prevStyle, { bottom: overlayBottom }]
|
|
5718
5848
|
});
|
|
5719
5849
|
}, [overlay, overlayBottom]);
|
|
5720
|
-
return /* @__PURE__ */ (0,
|
|
5721
|
-
header ? /* @__PURE__ */ (0,
|
|
5722
|
-
topBanner ? /* @__PURE__ */ (0,
|
|
5723
|
-
/* @__PURE__ */ (0,
|
|
5724
|
-
/* @__PURE__ */ (0,
|
|
5725
|
-
|
|
5850
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_react_native47.View, { style: [{ flex: 1 }, style], children: [
|
|
5851
|
+
header ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_react_native47.View, { children: header }) : null,
|
|
5852
|
+
topBanner ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_react_native47.View, { style: { paddingHorizontal: theme.spacing.lg, paddingTop: theme.spacing.sm }, children: topBanner }) : null,
|
|
5853
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_react_native47.View, { style: { flex: 1 }, children: [
|
|
5854
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
|
|
5855
|
+
import_react_native47.View,
|
|
5726
5856
|
{
|
|
5727
5857
|
style: { flex: 1 },
|
|
5728
5858
|
children: [
|
|
5729
|
-
/* @__PURE__ */ (0,
|
|
5859
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
5730
5860
|
ChatMessageList,
|
|
5731
5861
|
{
|
|
5732
5862
|
ref: listRef,
|
|
@@ -5741,19 +5871,19 @@ function ChatPage({
|
|
|
5741
5871
|
]
|
|
5742
5872
|
}
|
|
5743
5873
|
),
|
|
5744
|
-
/* @__PURE__ */ (0,
|
|
5745
|
-
|
|
5874
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
5875
|
+
import_react_native47.View,
|
|
5746
5876
|
{
|
|
5747
5877
|
style: {
|
|
5748
5878
|
position: "absolute",
|
|
5749
5879
|
left: 0,
|
|
5750
5880
|
right: 0,
|
|
5751
5881
|
bottom: 0,
|
|
5752
|
-
paddingHorizontal: theme.spacing.
|
|
5882
|
+
paddingHorizontal: composerHorizontalPadding ?? theme.spacing.md,
|
|
5753
5883
|
paddingTop: theme.spacing.sm,
|
|
5754
5884
|
paddingBottom: footerBottomPadding
|
|
5755
5885
|
},
|
|
5756
|
-
children: /* @__PURE__ */ (0,
|
|
5886
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
5757
5887
|
ChatComposer,
|
|
5758
5888
|
{
|
|
5759
5889
|
...composer,
|
|
@@ -5768,15 +5898,15 @@ function ChatPage({
|
|
|
5768
5898
|
}
|
|
5769
5899
|
|
|
5770
5900
|
// src/components/chat/ScrollToBottomButton.tsx
|
|
5771
|
-
var
|
|
5772
|
-
var
|
|
5901
|
+
var React37 = __toESM(require("react"));
|
|
5902
|
+
var import_react_native48 = require("react-native");
|
|
5773
5903
|
var import_react_native_reanimated2 = __toESM(require("react-native-reanimated"));
|
|
5774
|
-
var
|
|
5904
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
5775
5905
|
function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
5776
5906
|
const theme = useTheme();
|
|
5777
5907
|
const progress = (0, import_react_native_reanimated2.useSharedValue)(visible ? 1 : 0);
|
|
5778
|
-
const [pressed, setPressed] =
|
|
5779
|
-
|
|
5908
|
+
const [pressed, setPressed] = React37.useState(false);
|
|
5909
|
+
React37.useEffect(() => {
|
|
5780
5910
|
progress.value = (0, import_react_native_reanimated2.withTiming)(visible ? 1 : 0, { duration: 200, easing: import_react_native_reanimated2.Easing.out(import_react_native_reanimated2.Easing.ease) });
|
|
5781
5911
|
}, [progress, visible]);
|
|
5782
5912
|
const animStyle = (0, import_react_native_reanimated2.useAnimatedStyle)(() => ({
|
|
@@ -5785,7 +5915,7 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5785
5915
|
}));
|
|
5786
5916
|
const bg = theme.scheme === "dark" ? "rgba(39,39,42,0.9)" : "rgba(244,244,245,0.95)";
|
|
5787
5917
|
const border = theme.scheme === "dark" ? withAlpha("#FFFFFF", 0.12) : withAlpha("#000000", 0.08);
|
|
5788
|
-
return /* @__PURE__ */ (0,
|
|
5918
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
5789
5919
|
import_react_native_reanimated2.default.View,
|
|
5790
5920
|
{
|
|
5791
5921
|
pointerEvents: visible ? "auto" : "none",
|
|
@@ -5799,8 +5929,8 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5799
5929
|
style,
|
|
5800
5930
|
animStyle
|
|
5801
5931
|
],
|
|
5802
|
-
children: /* @__PURE__ */ (0,
|
|
5803
|
-
|
|
5932
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
5933
|
+
import_react_native48.View,
|
|
5804
5934
|
{
|
|
5805
5935
|
style: {
|
|
5806
5936
|
width: 44,
|
|
@@ -5818,8 +5948,8 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5818
5948
|
elevation: 5,
|
|
5819
5949
|
opacity: pressed ? 0.85 : 1
|
|
5820
5950
|
},
|
|
5821
|
-
children: /* @__PURE__ */ (0,
|
|
5822
|
-
|
|
5951
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
5952
|
+
import_react_native48.Pressable,
|
|
5823
5953
|
{
|
|
5824
5954
|
onPress,
|
|
5825
5955
|
onPressIn: () => setPressed(true),
|
|
@@ -5836,16 +5966,16 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5836
5966
|
}
|
|
5837
5967
|
|
|
5838
5968
|
// src/components/chat/ChatHeader.tsx
|
|
5839
|
-
var
|
|
5840
|
-
var
|
|
5969
|
+
var import_react_native49 = require("react-native");
|
|
5970
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
5841
5971
|
function ChatHeader({ left, right, center, style }) {
|
|
5842
|
-
const flattenedStyle =
|
|
5972
|
+
const flattenedStyle = import_react_native49.StyleSheet.flatten([
|
|
5843
5973
|
{
|
|
5844
5974
|
paddingTop: 0
|
|
5845
5975
|
},
|
|
5846
5976
|
style
|
|
5847
5977
|
]);
|
|
5848
|
-
return /* @__PURE__ */ (0,
|
|
5978
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
5849
5979
|
StudioSheetHeader,
|
|
5850
5980
|
{
|
|
5851
5981
|
left,
|
|
@@ -5857,13 +5987,13 @@ function ChatHeader({ left, right, center, style }) {
|
|
|
5857
5987
|
}
|
|
5858
5988
|
|
|
5859
5989
|
// src/components/chat/ForkNoticeBanner.tsx
|
|
5860
|
-
var
|
|
5861
|
-
var
|
|
5990
|
+
var import_react_native50 = require("react-native");
|
|
5991
|
+
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
5862
5992
|
function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
5863
5993
|
const theme = useTheme();
|
|
5864
5994
|
const resolvedTitle = title ?? (isOwner ? "Remixed app" : "Remix app");
|
|
5865
5995
|
const resolvedDescription = description ?? (isOwner ? "Any changes you make will be a remix of the original app. You can view the edited version in the Remix tab in your apps page." : "Once you make edits, this remixed version will appear on your Remixed apps page.");
|
|
5866
|
-
return /* @__PURE__ */ (0,
|
|
5996
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
5867
5997
|
Card,
|
|
5868
5998
|
{
|
|
5869
5999
|
variant: "surfaceRaised",
|
|
@@ -5878,8 +6008,8 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
|
5878
6008
|
},
|
|
5879
6009
|
style
|
|
5880
6010
|
],
|
|
5881
|
-
children: /* @__PURE__ */ (0,
|
|
5882
|
-
/* @__PURE__ */ (0,
|
|
6011
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_react_native50.View, { style: { minWidth: 0 }, children: [
|
|
6012
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
5883
6013
|
Text,
|
|
5884
6014
|
{
|
|
5885
6015
|
style: {
|
|
@@ -5893,7 +6023,7 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
|
5893
6023
|
children: resolvedTitle
|
|
5894
6024
|
}
|
|
5895
6025
|
),
|
|
5896
|
-
/* @__PURE__ */ (0,
|
|
6026
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
5897
6027
|
Text,
|
|
5898
6028
|
{
|
|
5899
6029
|
style: {
|
|
@@ -5911,7 +6041,7 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
|
5911
6041
|
}
|
|
5912
6042
|
|
|
5913
6043
|
// src/studio/ui/ChatPanel.tsx
|
|
5914
|
-
var
|
|
6044
|
+
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
5915
6045
|
function ChatPanel({
|
|
5916
6046
|
title = "Chat",
|
|
5917
6047
|
autoFocusComposer = false,
|
|
@@ -5931,9 +6061,9 @@ function ChatPanel({
|
|
|
5931
6061
|
onStartDraw,
|
|
5932
6062
|
onSend
|
|
5933
6063
|
}) {
|
|
5934
|
-
const listRef =
|
|
5935
|
-
const [nearBottom, setNearBottom] =
|
|
5936
|
-
const handleSend =
|
|
6064
|
+
const listRef = React38.useRef(null);
|
|
6065
|
+
const [nearBottom, setNearBottom] = React38.useState(true);
|
|
6066
|
+
const handleSend = React38.useCallback(
|
|
5937
6067
|
async (text, composerAttachments) => {
|
|
5938
6068
|
const all = composerAttachments ?? attachments;
|
|
5939
6069
|
await onSend(text, all.length > 0 ? all : void 0);
|
|
@@ -5947,25 +6077,25 @@ function ChatPanel({
|
|
|
5947
6077
|
},
|
|
5948
6078
|
[attachments, nearBottom, onClearAttachments, onSend]
|
|
5949
6079
|
);
|
|
5950
|
-
const handleScrollToBottom =
|
|
6080
|
+
const handleScrollToBottom = React38.useCallback(() => {
|
|
5951
6081
|
var _a;
|
|
5952
6082
|
(_a = listRef.current) == null ? void 0 : _a.scrollToBottom({ animated: true });
|
|
5953
6083
|
}, []);
|
|
5954
|
-
const header = /* @__PURE__ */ (0,
|
|
6084
|
+
const header = /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
5955
6085
|
ChatHeader,
|
|
5956
6086
|
{
|
|
5957
|
-
left: /* @__PURE__ */ (0,
|
|
5958
|
-
/* @__PURE__ */ (0,
|
|
5959
|
-
onNavigateHome ? /* @__PURE__ */ (0,
|
|
6087
|
+
left: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_native51.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
6088
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(StudioSheetHeaderIconButton, { onPress: onBack, accessibilityLabel: "Back", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(IconBack, { size: 20, colorToken: "floatingContent" }) }),
|
|
6089
|
+
onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(IconHome, { size: 20, colorToken: "floatingContent" }) }) : null
|
|
5960
6090
|
] }),
|
|
5961
|
-
right: /* @__PURE__ */ (0,
|
|
5962
|
-
onStartDraw ? /* @__PURE__ */ (0,
|
|
5963
|
-
/* @__PURE__ */ (0,
|
|
6091
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_native51.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
6092
|
+
onStartDraw ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(StudioSheetHeaderIconButton, { onPress: onStartDraw, accessibilityLabel: "Draw", intent: "danger", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(IconDraw, { size: 20, colorToken: "onDanger" }) }) : null,
|
|
6093
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(IconClose, { size: 20, colorToken: "floatingContent" }) })
|
|
5964
6094
|
] }),
|
|
5965
6095
|
center: null
|
|
5966
6096
|
}
|
|
5967
6097
|
);
|
|
5968
|
-
const topBanner = shouldForkOnEdit ? /* @__PURE__ */ (0,
|
|
6098
|
+
const topBanner = shouldForkOnEdit ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
5969
6099
|
ForkNoticeBanner,
|
|
5970
6100
|
{
|
|
5971
6101
|
isOwner: !shouldForkOnEdit,
|
|
@@ -5974,32 +6104,33 @@ function ChatPanel({
|
|
|
5974
6104
|
) : null;
|
|
5975
6105
|
const showMessagesLoading = Boolean(loading) && messages.length === 0 || forking;
|
|
5976
6106
|
if (showMessagesLoading) {
|
|
5977
|
-
return /* @__PURE__ */ (0,
|
|
5978
|
-
/* @__PURE__ */ (0,
|
|
5979
|
-
topBanner ? /* @__PURE__ */ (0,
|
|
5980
|
-
/* @__PURE__ */ (0,
|
|
5981
|
-
/* @__PURE__ */ (0,
|
|
5982
|
-
/* @__PURE__ */ (0,
|
|
5983
|
-
/* @__PURE__ */ (0,
|
|
6107
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_native51.View, { style: { flex: 1 }, children: [
|
|
6108
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.View, { children: header }),
|
|
6109
|
+
topBanner ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.View, { style: { paddingHorizontal: 16, paddingTop: 8 }, children: topBanner }) : null,
|
|
6110
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_native51.View, { style: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 24, paddingVertical: 12 }, children: [
|
|
6111
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.ActivityIndicator, {}),
|
|
6112
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.View, { style: { height: 12 } }),
|
|
6113
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Text, { variant: "bodyMuted", children: forking ? "Creating your copy\u2026" : "Loading messages\u2026" })
|
|
5984
6114
|
] })
|
|
5985
6115
|
] });
|
|
5986
6116
|
}
|
|
5987
|
-
return /* @__PURE__ */ (0,
|
|
6117
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
5988
6118
|
ChatPage,
|
|
5989
6119
|
{
|
|
5990
6120
|
header,
|
|
5991
6121
|
messages,
|
|
5992
6122
|
showTypingIndicator,
|
|
5993
6123
|
topBanner,
|
|
6124
|
+
composerHorizontalPadding: 0,
|
|
5994
6125
|
listRef,
|
|
5995
6126
|
onNearBottomChange: setNearBottom,
|
|
5996
|
-
overlay: /* @__PURE__ */ (0,
|
|
6127
|
+
overlay: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
5997
6128
|
ScrollToBottomButton,
|
|
5998
6129
|
{
|
|
5999
6130
|
visible: !nearBottom,
|
|
6000
6131
|
onPress: handleScrollToBottom,
|
|
6001
6132
|
style: { bottom: 80 },
|
|
6002
|
-
children: /* @__PURE__ */ (0,
|
|
6133
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(IconArrowDown, { size: 20, colorToken: "floatingContent" })
|
|
6003
6134
|
}
|
|
6004
6135
|
),
|
|
6005
6136
|
composer: {
|
|
@@ -6020,12 +6151,12 @@ function ChatPanel({
|
|
|
6020
6151
|
}
|
|
6021
6152
|
|
|
6022
6153
|
// src/components/dialogs/ConfirmMergeRequestDialog.tsx
|
|
6023
|
-
var
|
|
6024
|
-
var
|
|
6154
|
+
var React39 = __toESM(require("react"));
|
|
6155
|
+
var import_react_native53 = require("react-native");
|
|
6025
6156
|
|
|
6026
6157
|
// src/components/primitives/Modal.tsx
|
|
6027
|
-
var
|
|
6028
|
-
var
|
|
6158
|
+
var import_react_native52 = require("react-native");
|
|
6159
|
+
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
6029
6160
|
function Modal({
|
|
6030
6161
|
visible,
|
|
6031
6162
|
onRequestClose,
|
|
@@ -6034,30 +6165,30 @@ function Modal({
|
|
|
6034
6165
|
contentStyle
|
|
6035
6166
|
}) {
|
|
6036
6167
|
const theme = useTheme();
|
|
6037
|
-
return /* @__PURE__ */ (0,
|
|
6038
|
-
|
|
6168
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
6169
|
+
import_react_native52.Modal,
|
|
6039
6170
|
{
|
|
6040
6171
|
visible,
|
|
6041
6172
|
transparent: true,
|
|
6042
6173
|
animationType: "fade",
|
|
6043
6174
|
onRequestClose,
|
|
6044
|
-
children: /* @__PURE__ */ (0,
|
|
6045
|
-
/* @__PURE__ */ (0,
|
|
6046
|
-
|
|
6175
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_react_native52.View, { style: { flex: 1, backgroundColor: theme.colors.backdrop, justifyContent: "center", padding: theme.spacing.lg }, children: [
|
|
6176
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
6177
|
+
import_react_native52.Pressable,
|
|
6047
6178
|
{
|
|
6048
6179
|
accessibilityRole: "button",
|
|
6049
6180
|
onPress: dismissOnBackdropPress ? onRequestClose : void 0,
|
|
6050
6181
|
style: { position: "absolute", inset: 0 }
|
|
6051
6182
|
}
|
|
6052
6183
|
),
|
|
6053
|
-
/* @__PURE__ */ (0,
|
|
6184
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Card, { variant: "surfaceRaised", padded: true, style: [{ borderRadius: theme.radii.xl }, contentStyle], children })
|
|
6054
6185
|
] })
|
|
6055
6186
|
}
|
|
6056
6187
|
);
|
|
6057
6188
|
}
|
|
6058
6189
|
|
|
6059
6190
|
// src/components/dialogs/ConfirmMergeRequestDialog.tsx
|
|
6060
|
-
var
|
|
6191
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
6061
6192
|
function ConfirmMergeRequestDialog({
|
|
6062
6193
|
visible,
|
|
6063
6194
|
onOpenChange,
|
|
@@ -6068,14 +6199,14 @@ function ConfirmMergeRequestDialog({
|
|
|
6068
6199
|
onTestFirst
|
|
6069
6200
|
}) {
|
|
6070
6201
|
const theme = useTheme();
|
|
6071
|
-
const close =
|
|
6202
|
+
const close = React39.useCallback(() => onOpenChange(false), [onOpenChange]);
|
|
6072
6203
|
const canConfirm = Boolean(mergeRequest) && !approveDisabled;
|
|
6073
|
-
const handleConfirm =
|
|
6204
|
+
const handleConfirm = React39.useCallback(() => {
|
|
6074
6205
|
if (!mergeRequest) return;
|
|
6075
6206
|
onOpenChange(false);
|
|
6076
6207
|
void onConfirm();
|
|
6077
6208
|
}, [mergeRequest, onConfirm, onOpenChange]);
|
|
6078
|
-
const handleTestFirst =
|
|
6209
|
+
const handleTestFirst = React39.useCallback(() => {
|
|
6079
6210
|
if (!mergeRequest) return;
|
|
6080
6211
|
onOpenChange(false);
|
|
6081
6212
|
void onTestFirst(mergeRequest);
|
|
@@ -6087,7 +6218,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6087
6218
|
justifyContent: "center",
|
|
6088
6219
|
alignSelf: "stretch"
|
|
6089
6220
|
};
|
|
6090
|
-
return /* @__PURE__ */ (0,
|
|
6221
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
|
|
6091
6222
|
Modal,
|
|
6092
6223
|
{
|
|
6093
6224
|
visible,
|
|
@@ -6098,7 +6229,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6098
6229
|
backgroundColor: theme.colors.background
|
|
6099
6230
|
},
|
|
6100
6231
|
children: [
|
|
6101
|
-
/* @__PURE__ */ (0,
|
|
6232
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react_native53.View, { children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6102
6233
|
Text,
|
|
6103
6234
|
{
|
|
6104
6235
|
style: {
|
|
@@ -6110,9 +6241,9 @@ function ConfirmMergeRequestDialog({
|
|
|
6110
6241
|
children: "Are you sure you want to approve this merge request?"
|
|
6111
6242
|
}
|
|
6112
6243
|
) }),
|
|
6113
|
-
/* @__PURE__ */ (0,
|
|
6114
|
-
/* @__PURE__ */ (0,
|
|
6115
|
-
|
|
6244
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_react_native53.View, { style: { marginTop: 16 }, children: [
|
|
6245
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6246
|
+
import_react_native53.View,
|
|
6116
6247
|
{
|
|
6117
6248
|
style: [
|
|
6118
6249
|
fullWidthButtonBase,
|
|
@@ -6121,22 +6252,22 @@ function ConfirmMergeRequestDialog({
|
|
|
6121
6252
|
opacity: canConfirm ? 1 : 0.5
|
|
6122
6253
|
}
|
|
6123
6254
|
],
|
|
6124
|
-
children: /* @__PURE__ */ (0,
|
|
6125
|
-
|
|
6255
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6256
|
+
import_react_native53.Pressable,
|
|
6126
6257
|
{
|
|
6127
6258
|
accessibilityRole: "button",
|
|
6128
6259
|
accessibilityLabel: "Approve Merge",
|
|
6129
6260
|
disabled: !canConfirm,
|
|
6130
6261
|
onPress: handleConfirm,
|
|
6131
6262
|
style: [fullWidthButtonBase, { flex: 1 }],
|
|
6132
|
-
children: /* @__PURE__ */ (0,
|
|
6263
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Text, { style: { textAlign: "center", color: theme.colors.onPrimary }, children: "Approve Merge" })
|
|
6133
6264
|
}
|
|
6134
6265
|
)
|
|
6135
6266
|
}
|
|
6136
6267
|
),
|
|
6137
|
-
/* @__PURE__ */ (0,
|
|
6138
|
-
/* @__PURE__ */ (0,
|
|
6139
|
-
|
|
6268
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react_native53.View, { style: { height: 8 } }),
|
|
6269
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6270
|
+
import_react_native53.View,
|
|
6140
6271
|
{
|
|
6141
6272
|
style: [
|
|
6142
6273
|
fullWidthButtonBase,
|
|
@@ -6147,22 +6278,22 @@ function ConfirmMergeRequestDialog({
|
|
|
6147
6278
|
opacity: isBuilding || !mergeRequest ? 0.5 : 1
|
|
6148
6279
|
}
|
|
6149
6280
|
],
|
|
6150
|
-
children: /* @__PURE__ */ (0,
|
|
6151
|
-
|
|
6281
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6282
|
+
import_react_native53.Pressable,
|
|
6152
6283
|
{
|
|
6153
6284
|
accessibilityRole: "button",
|
|
6154
6285
|
accessibilityLabel: isBuilding ? "Preparing\u2026" : "Test edits first",
|
|
6155
6286
|
disabled: isBuilding || !mergeRequest,
|
|
6156
6287
|
onPress: handleTestFirst,
|
|
6157
6288
|
style: [fullWidthButtonBase, { flex: 1 }],
|
|
6158
|
-
children: /* @__PURE__ */ (0,
|
|
6289
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Text, { style: { textAlign: "center", color: theme.colors.text }, children: isBuilding ? "Preparing\u2026" : "Test edits first" })
|
|
6159
6290
|
}
|
|
6160
6291
|
)
|
|
6161
6292
|
}
|
|
6162
6293
|
),
|
|
6163
|
-
/* @__PURE__ */ (0,
|
|
6164
|
-
/* @__PURE__ */ (0,
|
|
6165
|
-
|
|
6294
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react_native53.View, { style: { height: 8 } }),
|
|
6295
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6296
|
+
import_react_native53.View,
|
|
6166
6297
|
{
|
|
6167
6298
|
style: [
|
|
6168
6299
|
fullWidthButtonBase,
|
|
@@ -6172,14 +6303,14 @@ function ConfirmMergeRequestDialog({
|
|
|
6172
6303
|
borderColor: theme.colors.border
|
|
6173
6304
|
}
|
|
6174
6305
|
],
|
|
6175
|
-
children: /* @__PURE__ */ (0,
|
|
6176
|
-
|
|
6306
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6307
|
+
import_react_native53.Pressable,
|
|
6177
6308
|
{
|
|
6178
6309
|
accessibilityRole: "button",
|
|
6179
6310
|
accessibilityLabel: "Cancel",
|
|
6180
6311
|
onPress: close,
|
|
6181
6312
|
style: [fullWidthButtonBase, { flex: 1 }],
|
|
6182
|
-
children: /* @__PURE__ */ (0,
|
|
6313
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Text, { style: { textAlign: "center", color: theme.colors.text }, children: "Cancel" })
|
|
6183
6314
|
}
|
|
6184
6315
|
)
|
|
6185
6316
|
}
|
|
@@ -6191,7 +6322,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6191
6322
|
}
|
|
6192
6323
|
|
|
6193
6324
|
// src/studio/ui/ConfirmMergeFlow.tsx
|
|
6194
|
-
var
|
|
6325
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
6195
6326
|
function ConfirmMergeFlow({
|
|
6196
6327
|
visible,
|
|
6197
6328
|
onOpenChange,
|
|
@@ -6202,7 +6333,7 @@ function ConfirmMergeFlow({
|
|
|
6202
6333
|
onConfirm,
|
|
6203
6334
|
onTestFirst
|
|
6204
6335
|
}) {
|
|
6205
|
-
return /* @__PURE__ */ (0,
|
|
6336
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
6206
6337
|
ConfirmMergeRequestDialog,
|
|
6207
6338
|
{
|
|
6208
6339
|
visible,
|
|
@@ -6223,8 +6354,94 @@ function ConfirmMergeFlow({
|
|
|
6223
6354
|
);
|
|
6224
6355
|
}
|
|
6225
6356
|
|
|
6357
|
+
// src/studio/hooks/useOptimisticChatMessages.ts
|
|
6358
|
+
var React40 = __toESM(require("react"));
|
|
6359
|
+
function makeOptimisticId() {
|
|
6360
|
+
return `optimistic:${Date.now().toString(36)}:${Math.random().toString(36).slice(2, 10)}`;
|
|
6361
|
+
}
|
|
6362
|
+
function toEpochMs(createdAt) {
|
|
6363
|
+
if (createdAt == null) return 0;
|
|
6364
|
+
if (typeof createdAt === "number") return createdAt;
|
|
6365
|
+
if (createdAt instanceof Date) return createdAt.getTime();
|
|
6366
|
+
const t = Date.parse(String(createdAt));
|
|
6367
|
+
return Number.isFinite(t) ? t : 0;
|
|
6368
|
+
}
|
|
6369
|
+
function isOptimisticResolvedByServer(chatMessages, o) {
|
|
6370
|
+
if (o.failed) return false;
|
|
6371
|
+
const normalize = (s) => s.trim();
|
|
6372
|
+
let startIndex = -1;
|
|
6373
|
+
if (o.baseServerLastId) {
|
|
6374
|
+
startIndex = chatMessages.findIndex((m) => m.id === o.baseServerLastId);
|
|
6375
|
+
}
|
|
6376
|
+
const candidates = startIndex >= 0 ? chatMessages.slice(startIndex + 1) : chatMessages;
|
|
6377
|
+
const target = normalize(o.content);
|
|
6378
|
+
for (const m of candidates) {
|
|
6379
|
+
if (m.author !== "human") continue;
|
|
6380
|
+
if (normalize(m.content) !== target) continue;
|
|
6381
|
+
const serverMs = toEpochMs(m.createdAt);
|
|
6382
|
+
const optimisticMs = Date.parse(o.createdAtIso);
|
|
6383
|
+
if (Number.isFinite(optimisticMs) && optimisticMs > 0 && serverMs > 0) {
|
|
6384
|
+
if (serverMs + 12e4 < optimisticMs) continue;
|
|
6385
|
+
}
|
|
6386
|
+
return true;
|
|
6387
|
+
}
|
|
6388
|
+
return false;
|
|
6389
|
+
}
|
|
6390
|
+
function useOptimisticChatMessages({
|
|
6391
|
+
threadId,
|
|
6392
|
+
shouldForkOnEdit,
|
|
6393
|
+
chatMessages,
|
|
6394
|
+
onSendChat
|
|
6395
|
+
}) {
|
|
6396
|
+
const [optimisticChat, setOptimisticChat] = React40.useState([]);
|
|
6397
|
+
React40.useEffect(() => {
|
|
6398
|
+
setOptimisticChat([]);
|
|
6399
|
+
}, [threadId]);
|
|
6400
|
+
const messages = React40.useMemo(() => {
|
|
6401
|
+
if (!optimisticChat || optimisticChat.length === 0) return chatMessages;
|
|
6402
|
+
const unresolved = optimisticChat.filter((o) => !isOptimisticResolvedByServer(chatMessages, o));
|
|
6403
|
+
if (unresolved.length === 0) return chatMessages;
|
|
6404
|
+
const optimisticAsChat = unresolved.map((o) => ({
|
|
6405
|
+
id: o.id,
|
|
6406
|
+
author: "human",
|
|
6407
|
+
content: o.content,
|
|
6408
|
+
createdAt: o.createdAtIso,
|
|
6409
|
+
kind: "optimistic",
|
|
6410
|
+
meta: o.failed ? { kind: "optimistic", event: "send.failed", status: "error" } : { kind: "optimistic", event: "send.pending", status: "info" }
|
|
6411
|
+
}));
|
|
6412
|
+
const merged = [...chatMessages, ...optimisticAsChat];
|
|
6413
|
+
merged.sort((a, b) => String(a.createdAt).localeCompare(String(b.createdAt)));
|
|
6414
|
+
return merged;
|
|
6415
|
+
}, [chatMessages, optimisticChat]);
|
|
6416
|
+
React40.useEffect(() => {
|
|
6417
|
+
if (optimisticChat.length === 0) return;
|
|
6418
|
+
setOptimisticChat((prev) => {
|
|
6419
|
+
if (prev.length === 0) return prev;
|
|
6420
|
+
const next = prev.filter((o) => !isOptimisticResolvedByServer(chatMessages, o) || o.failed);
|
|
6421
|
+
return next.length === prev.length ? prev : next;
|
|
6422
|
+
});
|
|
6423
|
+
}, [chatMessages, optimisticChat.length]);
|
|
6424
|
+
const onSend = React40.useCallback(
|
|
6425
|
+
async (text, attachments) => {
|
|
6426
|
+
if (shouldForkOnEdit) {
|
|
6427
|
+
await onSendChat(text, attachments);
|
|
6428
|
+
return;
|
|
6429
|
+
}
|
|
6430
|
+
const createdAtIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
6431
|
+
const baseServerLastId = chatMessages.length > 0 ? chatMessages[chatMessages.length - 1].id : null;
|
|
6432
|
+
const id = makeOptimisticId();
|
|
6433
|
+
setOptimisticChat((prev) => [...prev, { id, content: text, createdAtIso, baseServerLastId, failed: false }]);
|
|
6434
|
+
void Promise.resolve(onSendChat(text, attachments)).catch(() => {
|
|
6435
|
+
setOptimisticChat((prev) => prev.map((m) => m.id === id ? { ...m, failed: true } : m));
|
|
6436
|
+
});
|
|
6437
|
+
},
|
|
6438
|
+
[chatMessages, onSendChat, shouldForkOnEdit]
|
|
6439
|
+
);
|
|
6440
|
+
return { messages, onSend };
|
|
6441
|
+
}
|
|
6442
|
+
|
|
6226
6443
|
// src/studio/ui/StudioOverlay.tsx
|
|
6227
|
-
var
|
|
6444
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
6228
6445
|
function StudioOverlay({
|
|
6229
6446
|
captureTargetRef,
|
|
6230
6447
|
app,
|
|
@@ -6254,33 +6471,40 @@ function StudioOverlay({
|
|
|
6254
6471
|
onNavigateHome
|
|
6255
6472
|
}) {
|
|
6256
6473
|
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
|
|
6474
|
+
const { width } = (0, import_react_native54.useWindowDimensions)();
|
|
6475
|
+
const [sheetOpen, setSheetOpen] = React41.useState(false);
|
|
6476
|
+
const [activePage, setActivePage] = React41.useState("preview");
|
|
6477
|
+
const [drawing, setDrawing] = React41.useState(false);
|
|
6478
|
+
const [chatAttachments, setChatAttachments] = React41.useState([]);
|
|
6479
|
+
const [commentsAppId, setCommentsAppId] = React41.useState(null);
|
|
6480
|
+
const [commentsCount, setCommentsCount] = React41.useState(null);
|
|
6481
|
+
const threadId = (app == null ? void 0 : app.threadId) ?? null;
|
|
6482
|
+
const optimistic = useOptimisticChatMessages({
|
|
6483
|
+
threadId,
|
|
6484
|
+
shouldForkOnEdit,
|
|
6485
|
+
chatMessages,
|
|
6486
|
+
onSendChat
|
|
6487
|
+
});
|
|
6488
|
+
const [confirmMrId, setConfirmMrId] = React41.useState(null);
|
|
6489
|
+
const confirmMr = React41.useMemo(
|
|
6266
6490
|
() => confirmMrId ? incomingMergeRequests.find((m) => m.id === confirmMrId) ?? null : null,
|
|
6267
6491
|
[confirmMrId, incomingMergeRequests]
|
|
6268
6492
|
);
|
|
6269
|
-
const handleSheetOpenChange =
|
|
6493
|
+
const handleSheetOpenChange = React41.useCallback((open) => {
|
|
6270
6494
|
setSheetOpen(open);
|
|
6271
|
-
if (!open)
|
|
6495
|
+
if (!open) import_react_native54.Keyboard.dismiss();
|
|
6272
6496
|
}, []);
|
|
6273
|
-
const closeSheet =
|
|
6497
|
+
const closeSheet = React41.useCallback(() => {
|
|
6274
6498
|
handleSheetOpenChange(false);
|
|
6275
6499
|
}, [handleSheetOpenChange]);
|
|
6276
|
-
const openSheet =
|
|
6277
|
-
const goToChat =
|
|
6500
|
+
const openSheet = React41.useCallback(() => setSheetOpen(true), []);
|
|
6501
|
+
const goToChat = React41.useCallback(() => {
|
|
6278
6502
|
setActivePage("chat");
|
|
6279
6503
|
openSheet();
|
|
6280
6504
|
}, [openSheet]);
|
|
6281
|
-
const backToPreview =
|
|
6282
|
-
if (
|
|
6283
|
-
|
|
6505
|
+
const backToPreview = React41.useCallback(() => {
|
|
6506
|
+
if (import_react_native54.Platform.OS !== "ios") {
|
|
6507
|
+
import_react_native54.Keyboard.dismiss();
|
|
6284
6508
|
setActivePage("preview");
|
|
6285
6509
|
return;
|
|
6286
6510
|
}
|
|
@@ -6292,15 +6516,15 @@ function StudioOverlay({
|
|
|
6292
6516
|
clearTimeout(t);
|
|
6293
6517
|
setActivePage("preview");
|
|
6294
6518
|
};
|
|
6295
|
-
const sub =
|
|
6519
|
+
const sub = import_react_native54.Keyboard.addListener("keyboardDidHide", finalize);
|
|
6296
6520
|
const t = setTimeout(finalize, 350);
|
|
6297
|
-
|
|
6521
|
+
import_react_native54.Keyboard.dismiss();
|
|
6298
6522
|
}, []);
|
|
6299
|
-
const startDraw =
|
|
6523
|
+
const startDraw = React41.useCallback(() => {
|
|
6300
6524
|
setDrawing(true);
|
|
6301
6525
|
closeSheet();
|
|
6302
6526
|
}, [closeSheet]);
|
|
6303
|
-
const handleDrawCapture =
|
|
6527
|
+
const handleDrawCapture = React41.useCallback(
|
|
6304
6528
|
(dataUrl) => {
|
|
6305
6529
|
setChatAttachments((prev) => [...prev, dataUrl]);
|
|
6306
6530
|
setDrawing(false);
|
|
@@ -6309,7 +6533,7 @@ function StudioOverlay({
|
|
|
6309
6533
|
},
|
|
6310
6534
|
[openSheet]
|
|
6311
6535
|
);
|
|
6312
|
-
const toggleSheet =
|
|
6536
|
+
const toggleSheet = React41.useCallback(async () => {
|
|
6313
6537
|
if (!sheetOpen) {
|
|
6314
6538
|
const shouldExitTest = Boolean(testingMrId) || isTesting;
|
|
6315
6539
|
if (shouldExitTest) {
|
|
@@ -6321,7 +6545,7 @@ function StudioOverlay({
|
|
|
6321
6545
|
closeSheet();
|
|
6322
6546
|
}
|
|
6323
6547
|
}, [closeSheet, isTesting, onRestoreBase, sheetOpen, testingMrId]);
|
|
6324
|
-
const handleTestMr =
|
|
6548
|
+
const handleTestMr = React41.useCallback(
|
|
6325
6549
|
async (mr) => {
|
|
6326
6550
|
if (!onTestMr) return;
|
|
6327
6551
|
await onTestMr(mr);
|
|
@@ -6329,14 +6553,14 @@ function StudioOverlay({
|
|
|
6329
6553
|
},
|
|
6330
6554
|
[closeSheet, onTestMr]
|
|
6331
6555
|
);
|
|
6332
|
-
return /* @__PURE__ */ (0,
|
|
6333
|
-
/* @__PURE__ */ (0,
|
|
6334
|
-
/* @__PURE__ */ (0,
|
|
6556
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_jsx_runtime57.Fragment, { children: [
|
|
6557
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(EdgeGlowFrame, { visible: isTesting, role: "accent", thickness: 40, intensity: 1 }),
|
|
6558
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(StudioBottomSheet, { open: sheetOpen, onOpenChange: handleSheetOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
6335
6559
|
StudioSheetPager,
|
|
6336
6560
|
{
|
|
6337
6561
|
activePage,
|
|
6338
6562
|
width,
|
|
6339
|
-
preview: /* @__PURE__ */ (0,
|
|
6563
|
+
preview: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
6340
6564
|
PreviewPanel,
|
|
6341
6565
|
{
|
|
6342
6566
|
app,
|
|
@@ -6362,10 +6586,10 @@ function StudioOverlay({
|
|
|
6362
6586
|
commentCountOverride: commentsCount ?? void 0
|
|
6363
6587
|
}
|
|
6364
6588
|
),
|
|
6365
|
-
chat: /* @__PURE__ */ (0,
|
|
6589
|
+
chat: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
6366
6590
|
ChatPanel,
|
|
6367
6591
|
{
|
|
6368
|
-
messages:
|
|
6592
|
+
messages: optimistic.messages,
|
|
6369
6593
|
showTypingIndicator: chatShowTypingIndicator,
|
|
6370
6594
|
loading: chatLoading,
|
|
6371
6595
|
sendDisabled: chatSendDisabled,
|
|
@@ -6380,12 +6604,12 @@ function StudioOverlay({
|
|
|
6380
6604
|
onClose: closeSheet,
|
|
6381
6605
|
onNavigateHome,
|
|
6382
6606
|
onStartDraw: startDraw,
|
|
6383
|
-
onSend:
|
|
6607
|
+
onSend: optimistic.onSend
|
|
6384
6608
|
}
|
|
6385
6609
|
)
|
|
6386
6610
|
}
|
|
6387
6611
|
) }),
|
|
6388
|
-
/* @__PURE__ */ (0,
|
|
6612
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
6389
6613
|
FloatingDraggableButton,
|
|
6390
6614
|
{
|
|
6391
6615
|
visible: !sheetOpen && !drawing,
|
|
@@ -6393,10 +6617,10 @@ function StudioOverlay({
|
|
|
6393
6617
|
badgeCount: incomingMergeRequests.length,
|
|
6394
6618
|
onPress: toggleSheet,
|
|
6395
6619
|
isLoading: (app == null ? void 0 : app.status) === "editing",
|
|
6396
|
-
children: /* @__PURE__ */ (0,
|
|
6620
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_react_native54.View, { style: { width: 28, height: 28, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(MergeIcon, { width: 24, height: 24, color: theme.colors.floatingContent }) })
|
|
6397
6621
|
}
|
|
6398
6622
|
),
|
|
6399
|
-
/* @__PURE__ */ (0,
|
|
6623
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
6400
6624
|
DrawModeOverlay,
|
|
6401
6625
|
{
|
|
6402
6626
|
visible: drawing,
|
|
@@ -6405,7 +6629,7 @@ function StudioOverlay({
|
|
|
6405
6629
|
onCapture: handleDrawCapture
|
|
6406
6630
|
}
|
|
6407
6631
|
),
|
|
6408
|
-
/* @__PURE__ */ (0,
|
|
6632
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
6409
6633
|
ConfirmMergeFlow,
|
|
6410
6634
|
{
|
|
6411
6635
|
visible: Boolean(confirmMr),
|
|
@@ -6418,7 +6642,7 @@ function StudioOverlay({
|
|
|
6418
6642
|
onTestFirst: handleTestMr
|
|
6419
6643
|
}
|
|
6420
6644
|
),
|
|
6421
|
-
/* @__PURE__ */ (0,
|
|
6645
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
6422
6646
|
AppCommentsSheet,
|
|
6423
6647
|
{
|
|
6424
6648
|
appId: commentsAppId,
|
|
@@ -6431,7 +6655,7 @@ function StudioOverlay({
|
|
|
6431
6655
|
}
|
|
6432
6656
|
|
|
6433
6657
|
// src/studio/ComergeStudio.tsx
|
|
6434
|
-
var
|
|
6658
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
6435
6659
|
function ComergeStudio({
|
|
6436
6660
|
appId,
|
|
6437
6661
|
apiKey,
|
|
@@ -6439,17 +6663,17 @@ function ComergeStudio({
|
|
|
6439
6663
|
onNavigateHome,
|
|
6440
6664
|
style
|
|
6441
6665
|
}) {
|
|
6442
|
-
const [activeAppId, setActiveAppId] =
|
|
6443
|
-
const [runtimeAppId, setRuntimeAppId] =
|
|
6444
|
-
const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] =
|
|
6445
|
-
const platform =
|
|
6446
|
-
|
|
6666
|
+
const [activeAppId, setActiveAppId] = React42.useState(appId);
|
|
6667
|
+
const [runtimeAppId, setRuntimeAppId] = React42.useState(appId);
|
|
6668
|
+
const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] = React42.useState(null);
|
|
6669
|
+
const platform = React42.useMemo(() => import_react_native55.Platform.OS === "ios" ? "ios" : "android", []);
|
|
6670
|
+
React42.useEffect(() => {
|
|
6447
6671
|
setActiveAppId(appId);
|
|
6448
6672
|
setRuntimeAppId(appId);
|
|
6449
6673
|
setPendingRuntimeTargetAppId(null);
|
|
6450
6674
|
}, [appId]);
|
|
6451
|
-
const captureTargetRef =
|
|
6452
|
-
return /* @__PURE__ */ (0,
|
|
6675
|
+
const captureTargetRef = React42.useRef(null);
|
|
6676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(StudioBootstrap, { apiKey, children: ({ userId }) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_bottom_sheet6.BottomSheetModalProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(LiquidGlassResetProvider, { resetTriggers: [appId, activeAppId, runtimeAppId], children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
6453
6677
|
ComergeStudioInner,
|
|
6454
6678
|
{
|
|
6455
6679
|
userId,
|
|
@@ -6465,7 +6689,7 @@ function ComergeStudio({
|
|
|
6465
6689
|
captureTargetRef,
|
|
6466
6690
|
style
|
|
6467
6691
|
}
|
|
6468
|
-
) }) });
|
|
6692
|
+
) }) }) });
|
|
6469
6693
|
}
|
|
6470
6694
|
function ComergeStudioInner({
|
|
6471
6695
|
userId,
|
|
@@ -6484,11 +6708,11 @@ function ComergeStudioInner({
|
|
|
6484
6708
|
const { app, loading: appLoading } = useApp(activeAppId);
|
|
6485
6709
|
const { app: runtimeAppFromHook } = useApp(runtimeAppId, { enabled: runtimeAppId !== activeAppId });
|
|
6486
6710
|
const runtimeApp = runtimeAppId === activeAppId ? app : runtimeAppFromHook;
|
|
6487
|
-
const sawEditingOnPendingTargetRef =
|
|
6488
|
-
|
|
6711
|
+
const sawEditingOnPendingTargetRef = React42.useRef(false);
|
|
6712
|
+
React42.useEffect(() => {
|
|
6489
6713
|
sawEditingOnPendingTargetRef.current = false;
|
|
6490
6714
|
}, [pendingRuntimeTargetAppId]);
|
|
6491
|
-
|
|
6715
|
+
React42.useEffect(() => {
|
|
6492
6716
|
if (!pendingRuntimeTargetAppId) return;
|
|
6493
6717
|
if (activeAppId !== pendingRuntimeTargetAppId) return;
|
|
6494
6718
|
if ((app == null ? void 0 : app.status) === "editing") {
|
|
@@ -6505,13 +6729,38 @@ function ComergeStudioInner({
|
|
|
6505
6729
|
platform,
|
|
6506
6730
|
canRequestLatest: (runtimeApp == null ? void 0 : runtimeApp.status) === "ready"
|
|
6507
6731
|
});
|
|
6732
|
+
const sawEditingOnActiveAppRef = React42.useRef(false);
|
|
6733
|
+
const [showPostEditPreparing, setShowPostEditPreparing] = React42.useState(false);
|
|
6734
|
+
React42.useEffect(() => {
|
|
6735
|
+
sawEditingOnActiveAppRef.current = false;
|
|
6736
|
+
setShowPostEditPreparing(false);
|
|
6737
|
+
}, [activeAppId]);
|
|
6738
|
+
React42.useEffect(() => {
|
|
6739
|
+
if (!(app == null ? void 0 : app.id)) return;
|
|
6740
|
+
if (app.status === "editing") {
|
|
6741
|
+
sawEditingOnActiveAppRef.current = true;
|
|
6742
|
+
setShowPostEditPreparing(false);
|
|
6743
|
+
return;
|
|
6744
|
+
}
|
|
6745
|
+
if (app.status === "ready" && sawEditingOnActiveAppRef.current) {
|
|
6746
|
+
setShowPostEditPreparing(true);
|
|
6747
|
+
sawEditingOnActiveAppRef.current = false;
|
|
6748
|
+
}
|
|
6749
|
+
}, [app == null ? void 0 : app.id, app == null ? void 0 : app.status]);
|
|
6750
|
+
React42.useEffect(() => {
|
|
6751
|
+
if (!showPostEditPreparing) return;
|
|
6752
|
+
const stillProcessingBaseBundle = bundle.loading && bundle.loadingMode === "base" && !bundle.isTesting;
|
|
6753
|
+
if (!stillProcessingBaseBundle) {
|
|
6754
|
+
setShowPostEditPreparing(false);
|
|
6755
|
+
}
|
|
6756
|
+
}, [showPostEditPreparing, bundle.loading, bundle.loadingMode, bundle.isTesting]);
|
|
6508
6757
|
const threadId = (app == null ? void 0 : app.threadId) ?? "";
|
|
6509
6758
|
const thread = useThreadMessages(threadId);
|
|
6510
6759
|
const mergeRequests = useMergeRequests({ appId: activeAppId });
|
|
6511
|
-
const hasOpenOutgoingMr =
|
|
6760
|
+
const hasOpenOutgoingMr = React42.useMemo(() => {
|
|
6512
6761
|
return mergeRequests.lists.outgoing.some((mr) => mr.status === "open");
|
|
6513
6762
|
}, [mergeRequests.lists.outgoing]);
|
|
6514
|
-
const incomingReviewMrs =
|
|
6763
|
+
const incomingReviewMrs = React42.useMemo(() => {
|
|
6515
6764
|
if (!userId) return mergeRequests.lists.incoming;
|
|
6516
6765
|
return mergeRequests.lists.incoming.filter((mr) => mr.createdBy !== userId);
|
|
6517
6766
|
}, [mergeRequests.lists.incoming, userId]);
|
|
@@ -6533,18 +6782,26 @@ function ComergeStudioInner({
|
|
|
6533
6782
|
uploadAttachments: uploader.uploadBase64Images
|
|
6534
6783
|
});
|
|
6535
6784
|
const chatSendDisabled = hasNoOutcomeAfterLastHuman(thread.raw);
|
|
6536
|
-
const [processingMrId, setProcessingMrId] =
|
|
6537
|
-
const [testingMrId, setTestingMrId] =
|
|
6538
|
-
const chatShowTypingIndicator =
|
|
6785
|
+
const [processingMrId, setProcessingMrId] = React42.useState(null);
|
|
6786
|
+
const [testingMrId, setTestingMrId] = React42.useState(null);
|
|
6787
|
+
const chatShowTypingIndicator = React42.useMemo(() => {
|
|
6539
6788
|
var _a;
|
|
6540
6789
|
if (!thread.raw || thread.raw.length === 0) return false;
|
|
6541
6790
|
const last = thread.raw[thread.raw.length - 1];
|
|
6542
6791
|
const payloadType = typeof ((_a = last.payload) == null ? void 0 : _a.type) === "string" ? String(last.payload.type) : void 0;
|
|
6543
6792
|
return payloadType !== "outcome";
|
|
6544
6793
|
}, [thread.raw]);
|
|
6545
|
-
return /* @__PURE__ */ (0,
|
|
6546
|
-
/* @__PURE__ */ (0,
|
|
6547
|
-
|
|
6794
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react_native55.View, { style: [{ flex: 1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_react_native55.View, { ref: captureTargetRef, style: { flex: 1 }, collapsable: false, children: [
|
|
6795
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
6796
|
+
RuntimeRenderer,
|
|
6797
|
+
{
|
|
6798
|
+
appKey,
|
|
6799
|
+
bundlePath: bundle.bundlePath,
|
|
6800
|
+
forcePreparing: showPostEditPreparing,
|
|
6801
|
+
renderToken: bundle.renderToken
|
|
6802
|
+
}
|
|
6803
|
+
),
|
|
6804
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
6548
6805
|
StudioOverlay,
|
|
6549
6806
|
{
|
|
6550
6807
|
captureTargetRef,
|