@comergehq/studio 0.1.7 → 0.1.9
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 +703 -611
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +459 -367
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/chat/ChatComposer.tsx +3 -1
- package/src/components/chat/ChatMessageList.tsx +29 -10
- package/src/components/chat/ChatPage.tsx +25 -30
- package/src/components/comments/AppCommentsSheet.tsx +6 -1
- package/src/components/comments/useIosKeyboardSnapFix.ts +11 -3
- package/src/components/studio-sheet/StudioBottomSheet.tsx +25 -10
- package/src/studio/hooks/useApp.ts +10 -4
- package/src/studio/hooks/useForegroundSignal.ts +37 -0
- package/src/studio/hooks/useThreadMessages.ts +25 -5
- package/src/studio/ui/ChatPanel.tsx +9 -3
- package/src/studio/ui/StudioOverlay.tsx +8 -4
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 React39 = __toESM(require("react"));
|
|
40
|
+
var import_react_native53 = require("react-native");
|
|
41
41
|
var import_bottom_sheet6 = require("@gorhom/bottom-sheet");
|
|
42
42
|
|
|
43
43
|
// src/studio/bootstrap/StudioBootstrap.tsx
|
|
@@ -393,7 +393,7 @@ function StudioBootstrap({ children, fallback, renderError, apiKey }) {
|
|
|
393
393
|
}
|
|
394
394
|
|
|
395
395
|
// src/studio/hooks/useApp.ts
|
|
396
|
-
var
|
|
396
|
+
var React3 = __toESM(require("react"));
|
|
397
397
|
|
|
398
398
|
// src/core/services/http/index.ts
|
|
399
399
|
var import_axios2 = __toESM(require("axios"));
|
|
@@ -692,13 +692,40 @@ var AppsRepositoryImpl = class extends BaseRepository {
|
|
|
692
692
|
};
|
|
693
693
|
var appsRepository = new AppsRepositoryImpl(appsRemoteDataSource);
|
|
694
694
|
|
|
695
|
+
// src/studio/hooks/useForegroundSignal.ts
|
|
696
|
+
var React2 = __toESM(require("react"));
|
|
697
|
+
var import_react_native4 = require("react-native");
|
|
698
|
+
function useForegroundSignal(enabled = true) {
|
|
699
|
+
const [signal, setSignal] = React2.useState(0);
|
|
700
|
+
const lastStateRef = React2.useRef(import_react_native4.AppState.currentState);
|
|
701
|
+
React2.useEffect(() => {
|
|
702
|
+
if (!enabled) return;
|
|
703
|
+
const sub = import_react_native4.AppState.addEventListener("change", (nextState) => {
|
|
704
|
+
var _a, _b;
|
|
705
|
+
const prevState = lastStateRef.current;
|
|
706
|
+
lastStateRef.current = nextState;
|
|
707
|
+
const didResume = (prevState === "background" || prevState === "inactive") && nextState === "active";
|
|
708
|
+
if (!didResume) return;
|
|
709
|
+
try {
|
|
710
|
+
const supabase = getSupabaseClient();
|
|
711
|
+
(_b = (_a = supabase == null ? void 0 : supabase.realtime) == null ? void 0 : _a.connect) == null ? void 0 : _b.call(_a);
|
|
712
|
+
} catch {
|
|
713
|
+
}
|
|
714
|
+
setSignal((s) => s + 1);
|
|
715
|
+
});
|
|
716
|
+
return () => sub.remove();
|
|
717
|
+
}, [enabled]);
|
|
718
|
+
return signal;
|
|
719
|
+
}
|
|
720
|
+
|
|
695
721
|
// src/studio/hooks/useApp.ts
|
|
696
722
|
function useApp(appId, options) {
|
|
697
723
|
const enabled = (options == null ? void 0 : options.enabled) ?? true;
|
|
698
|
-
const [app, setApp] =
|
|
699
|
-
const [loading, setLoading] =
|
|
700
|
-
const [error, setError] =
|
|
701
|
-
const
|
|
724
|
+
const [app, setApp] = React3.useState(null);
|
|
725
|
+
const [loading, setLoading] = React3.useState(false);
|
|
726
|
+
const [error, setError] = React3.useState(null);
|
|
727
|
+
const foregroundSignal = useForegroundSignal(enabled && Boolean(appId));
|
|
728
|
+
const mergeApp = React3.useCallback((prev, next) => {
|
|
702
729
|
const merged = {
|
|
703
730
|
...prev ?? {},
|
|
704
731
|
...next,
|
|
@@ -707,7 +734,7 @@ function useApp(appId, options) {
|
|
|
707
734
|
};
|
|
708
735
|
return merged;
|
|
709
736
|
}, []);
|
|
710
|
-
const fetchOnce =
|
|
737
|
+
const fetchOnce = React3.useCallback(async () => {
|
|
711
738
|
if (!enabled) return;
|
|
712
739
|
if (!appId) return;
|
|
713
740
|
setLoading(true);
|
|
@@ -722,34 +749,37 @@ function useApp(appId, options) {
|
|
|
722
749
|
setLoading(false);
|
|
723
750
|
}
|
|
724
751
|
}, [appId, enabled]);
|
|
725
|
-
|
|
752
|
+
React3.useEffect(() => {
|
|
726
753
|
if (!enabled) return;
|
|
727
754
|
void fetchOnce();
|
|
728
755
|
}, [enabled, fetchOnce]);
|
|
729
|
-
|
|
756
|
+
React3.useEffect(() => {
|
|
730
757
|
if (!enabled) return;
|
|
731
758
|
if (!appId) return;
|
|
732
759
|
const unsubscribe = appsRepository.subscribeApp(appId, {
|
|
733
760
|
onInsert: (a) => {
|
|
734
|
-
console.log("[useApp] onInsert", a);
|
|
735
761
|
setApp((prev) => mergeApp(prev, a));
|
|
736
762
|
},
|
|
737
763
|
onUpdate: (a) => {
|
|
738
|
-
console.log("[useApp] onUpdate", a);
|
|
739
764
|
setApp((prev) => mergeApp(prev, a));
|
|
740
765
|
},
|
|
741
766
|
onDelete: () => {
|
|
742
|
-
console.log("[useApp] onDelete");
|
|
743
767
|
setApp(null);
|
|
744
768
|
}
|
|
745
769
|
});
|
|
746
770
|
return unsubscribe;
|
|
747
|
-
}, [appId, enabled, mergeApp]);
|
|
771
|
+
}, [appId, enabled, mergeApp, foregroundSignal]);
|
|
772
|
+
React3.useEffect(() => {
|
|
773
|
+
if (!enabled) return;
|
|
774
|
+
if (!appId) return;
|
|
775
|
+
if (foregroundSignal <= 0) return;
|
|
776
|
+
void fetchOnce();
|
|
777
|
+
}, [appId, enabled, fetchOnce, foregroundSignal]);
|
|
748
778
|
return { app, loading, error, refetch: fetchOnce };
|
|
749
779
|
}
|
|
750
780
|
|
|
751
781
|
// src/studio/hooks/useThreadMessages.ts
|
|
752
|
-
var
|
|
782
|
+
var React4 = __toESM(require("react"));
|
|
753
783
|
|
|
754
784
|
// src/data/messages/remote.ts
|
|
755
785
|
var MessagesRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -850,44 +880,59 @@ function mapMessageToChatMessage(m) {
|
|
|
850
880
|
};
|
|
851
881
|
}
|
|
852
882
|
function useThreadMessages(threadId) {
|
|
853
|
-
const [raw, setRaw] =
|
|
854
|
-
const [loading, setLoading] =
|
|
855
|
-
const [error, setError] =
|
|
856
|
-
const
|
|
883
|
+
const [raw, setRaw] = React4.useState([]);
|
|
884
|
+
const [loading, setLoading] = React4.useState(false);
|
|
885
|
+
const [error, setError] = React4.useState(null);
|
|
886
|
+
const activeRequestIdRef = React4.useRef(0);
|
|
887
|
+
const foregroundSignal = useForegroundSignal(Boolean(threadId));
|
|
888
|
+
const upsertSorted = React4.useCallback((prev, m) => {
|
|
889
|
+
const next = prev.some((x) => x.id === m.id) ? prev.map((x) => x.id === m.id ? m : x) : [...prev, m];
|
|
890
|
+
next.sort((a, b) => String(a.createdAt).localeCompare(String(b.createdAt)));
|
|
891
|
+
return next;
|
|
892
|
+
}, []);
|
|
893
|
+
const refetch = React4.useCallback(async () => {
|
|
857
894
|
if (!threadId) {
|
|
858
895
|
setRaw([]);
|
|
859
896
|
return;
|
|
860
897
|
}
|
|
898
|
+
const requestId = ++activeRequestIdRef.current;
|
|
861
899
|
setLoading(true);
|
|
862
900
|
setError(null);
|
|
863
901
|
try {
|
|
864
902
|
const list = await messagesRepository.list(threadId);
|
|
865
|
-
|
|
903
|
+
if (activeRequestIdRef.current !== requestId) return;
|
|
904
|
+
setRaw([...list].sort((a, b) => String(a.createdAt).localeCompare(String(b.createdAt))));
|
|
866
905
|
} catch (e) {
|
|
906
|
+
if (activeRequestIdRef.current !== requestId) return;
|
|
867
907
|
setError(e instanceof Error ? e : new Error(String(e)));
|
|
868
908
|
setRaw([]);
|
|
869
909
|
} finally {
|
|
870
|
-
setLoading(false);
|
|
910
|
+
if (activeRequestIdRef.current === requestId) setLoading(false);
|
|
871
911
|
}
|
|
872
912
|
}, [threadId]);
|
|
873
|
-
|
|
913
|
+
React4.useEffect(() => {
|
|
874
914
|
void refetch();
|
|
875
915
|
}, [refetch]);
|
|
876
|
-
|
|
916
|
+
React4.useEffect(() => {
|
|
877
917
|
if (!threadId) return;
|
|
878
918
|
const unsubscribe = messagesRepository.subscribeThread(threadId, {
|
|
879
|
-
onInsert: (m) => setRaw((prev) =>
|
|
880
|
-
onUpdate: (m) => setRaw((prev) => prev
|
|
919
|
+
onInsert: (m) => setRaw((prev) => upsertSorted(prev, m)),
|
|
920
|
+
onUpdate: (m) => setRaw((prev) => upsertSorted(prev, m)),
|
|
881
921
|
onDelete: (m) => setRaw((prev) => prev.filter((x) => x.id !== m.id))
|
|
882
922
|
});
|
|
883
923
|
return unsubscribe;
|
|
884
|
-
}, [threadId]);
|
|
885
|
-
|
|
924
|
+
}, [threadId, upsertSorted, foregroundSignal]);
|
|
925
|
+
React4.useEffect(() => {
|
|
926
|
+
if (!threadId) return;
|
|
927
|
+
if (foregroundSignal <= 0) return;
|
|
928
|
+
void refetch();
|
|
929
|
+
}, [foregroundSignal, refetch, threadId]);
|
|
930
|
+
const messages = React4.useMemo(() => raw.map(mapMessageToChatMessage), [raw]);
|
|
886
931
|
return { raw, messages, loading, error, refetch };
|
|
887
932
|
}
|
|
888
933
|
|
|
889
934
|
// src/studio/hooks/useBundleManager.ts
|
|
890
|
-
var
|
|
935
|
+
var React5 = __toESM(require("react"));
|
|
891
936
|
var FileSystem = __toESM(require("expo-file-system/legacy"));
|
|
892
937
|
|
|
893
938
|
// src/data/apps/bundles/remote.ts
|
|
@@ -1060,19 +1105,19 @@ function useBundleManager({
|
|
|
1060
1105
|
platform,
|
|
1061
1106
|
canRequestLatest = true
|
|
1062
1107
|
}) {
|
|
1063
|
-
const [bundlePath, setBundlePath] =
|
|
1064
|
-
const [renderToken, setRenderToken] =
|
|
1065
|
-
const [loading, setLoading] =
|
|
1066
|
-
const [statusLabel, setStatusLabel] =
|
|
1067
|
-
const [error, setError] =
|
|
1068
|
-
const [isTesting, setIsTesting] =
|
|
1069
|
-
const baseRef =
|
|
1108
|
+
const [bundlePath, setBundlePath] = React5.useState(null);
|
|
1109
|
+
const [renderToken, setRenderToken] = React5.useState(0);
|
|
1110
|
+
const [loading, setLoading] = React5.useState(false);
|
|
1111
|
+
const [statusLabel, setStatusLabel] = React5.useState(null);
|
|
1112
|
+
const [error, setError] = React5.useState(null);
|
|
1113
|
+
const [isTesting, setIsTesting] = React5.useState(false);
|
|
1114
|
+
const baseRef = React5.useRef(base);
|
|
1070
1115
|
baseRef.current = base;
|
|
1071
|
-
const baseOpIdRef =
|
|
1072
|
-
const testOpIdRef =
|
|
1073
|
-
const activeLoadModeRef =
|
|
1074
|
-
const canRequestLatestRef =
|
|
1075
|
-
|
|
1116
|
+
const baseOpIdRef = React5.useRef(0);
|
|
1117
|
+
const testOpIdRef = React5.useRef(0);
|
|
1118
|
+
const activeLoadModeRef = React5.useRef(null);
|
|
1119
|
+
const canRequestLatestRef = React5.useRef(canRequestLatest);
|
|
1120
|
+
React5.useEffect(() => {
|
|
1076
1121
|
canRequestLatestRef.current = canRequestLatest;
|
|
1077
1122
|
if (!canRequestLatest) {
|
|
1078
1123
|
baseOpIdRef.current += 1;
|
|
@@ -1083,11 +1128,11 @@ function useBundleManager({
|
|
|
1083
1128
|
}
|
|
1084
1129
|
}
|
|
1085
1130
|
}, [canRequestLatest]);
|
|
1086
|
-
const lastBaseBundlePathRef =
|
|
1087
|
-
const lastBaseFingerprintRef =
|
|
1088
|
-
const initialHydratedBaseFromDiskRef =
|
|
1089
|
-
const hasCompletedFirstNetworkBaseLoadRef =
|
|
1090
|
-
const hydrateBaseFromDisk =
|
|
1131
|
+
const lastBaseBundlePathRef = React5.useRef(null);
|
|
1132
|
+
const lastBaseFingerprintRef = React5.useRef(null);
|
|
1133
|
+
const initialHydratedBaseFromDiskRef = React5.useRef(false);
|
|
1134
|
+
const hasCompletedFirstNetworkBaseLoadRef = React5.useRef(false);
|
|
1135
|
+
const hydrateBaseFromDisk = React5.useCallback(
|
|
1091
1136
|
async (appId, reason) => {
|
|
1092
1137
|
try {
|
|
1093
1138
|
const dir = bundlesCacheDir();
|
|
@@ -1112,13 +1157,13 @@ function useBundleManager({
|
|
|
1112
1157
|
},
|
|
1113
1158
|
[platform]
|
|
1114
1159
|
);
|
|
1115
|
-
|
|
1160
|
+
React5.useEffect(() => {
|
|
1116
1161
|
if (!base.appId) return;
|
|
1117
1162
|
initialHydratedBaseFromDiskRef.current = false;
|
|
1118
1163
|
hasCompletedFirstNetworkBaseLoadRef.current = false;
|
|
1119
1164
|
void hydrateBaseFromDisk(base.appId, "initial");
|
|
1120
1165
|
}, [base.appId, platform, hydrateBaseFromDisk]);
|
|
1121
|
-
const activateCachedBase =
|
|
1166
|
+
const activateCachedBase = React5.useCallback(
|
|
1122
1167
|
async (appId) => {
|
|
1123
1168
|
setIsTesting(false);
|
|
1124
1169
|
setStatusLabel(null);
|
|
@@ -1132,7 +1177,7 @@ function useBundleManager({
|
|
|
1132
1177
|
},
|
|
1133
1178
|
[hydrateBaseFromDisk]
|
|
1134
1179
|
);
|
|
1135
|
-
const load =
|
|
1180
|
+
const load = React5.useCallback(async (src, mode) => {
|
|
1136
1181
|
if (!src.appId) return;
|
|
1137
1182
|
const canRequestLatest2 = canRequestLatestRef.current;
|
|
1138
1183
|
if (mode === "base" && !canRequestLatest2) {
|
|
@@ -1187,13 +1232,13 @@ function useBundleManager({
|
|
|
1187
1232
|
if (activeLoadModeRef.current === mode) activeLoadModeRef.current = null;
|
|
1188
1233
|
}
|
|
1189
1234
|
}, [activateCachedBase, platform]);
|
|
1190
|
-
const loadBase =
|
|
1235
|
+
const loadBase = React5.useCallback(async () => {
|
|
1191
1236
|
await load(baseRef.current, "base");
|
|
1192
1237
|
}, [load]);
|
|
1193
|
-
const loadTest =
|
|
1238
|
+
const loadTest = React5.useCallback(async (src) => {
|
|
1194
1239
|
await load(src, "test");
|
|
1195
1240
|
}, [load]);
|
|
1196
|
-
const restoreBase =
|
|
1241
|
+
const restoreBase = React5.useCallback(async () => {
|
|
1197
1242
|
const src = baseRef.current;
|
|
1198
1243
|
if (!src.appId) return;
|
|
1199
1244
|
await activateCachedBase(src.appId);
|
|
@@ -1201,7 +1246,7 @@ function useBundleManager({
|
|
|
1201
1246
|
await load(src, "base");
|
|
1202
1247
|
}
|
|
1203
1248
|
}, [activateCachedBase, load]);
|
|
1204
|
-
|
|
1249
|
+
React5.useEffect(() => {
|
|
1205
1250
|
if (!canRequestLatest) return;
|
|
1206
1251
|
void loadBase();
|
|
1207
1252
|
}, [base.appId, base.commitId, platform, canRequestLatest, loadBase]);
|
|
@@ -1209,7 +1254,7 @@ function useBundleManager({
|
|
|
1209
1254
|
}
|
|
1210
1255
|
|
|
1211
1256
|
// src/studio/hooks/useMergeRequests.ts
|
|
1212
|
-
var
|
|
1257
|
+
var React6 = __toESM(require("react"));
|
|
1213
1258
|
|
|
1214
1259
|
// src/data/merge-requests/remote.ts
|
|
1215
1260
|
var MergeRequestsRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -1355,12 +1400,12 @@ function toUiStatus(status) {
|
|
|
1355
1400
|
}
|
|
1356
1401
|
function useMergeRequests(params) {
|
|
1357
1402
|
const { appId } = params;
|
|
1358
|
-
const [incoming, setIncoming] =
|
|
1359
|
-
const [outgoing, setOutgoing] =
|
|
1360
|
-
const [loading, setLoading] =
|
|
1361
|
-
const [error, setError] =
|
|
1362
|
-
const [creatorStatsById, setCreatorStatsById] =
|
|
1363
|
-
const pollUntilMerged =
|
|
1403
|
+
const [incoming, setIncoming] = React6.useState([]);
|
|
1404
|
+
const [outgoing, setOutgoing] = React6.useState([]);
|
|
1405
|
+
const [loading, setLoading] = React6.useState(false);
|
|
1406
|
+
const [error, setError] = React6.useState(null);
|
|
1407
|
+
const [creatorStatsById, setCreatorStatsById] = React6.useState({});
|
|
1408
|
+
const pollUntilMerged = React6.useCallback(async (mrId) => {
|
|
1364
1409
|
const startedAt = Date.now();
|
|
1365
1410
|
const timeoutMs = 2 * 60 * 1e3;
|
|
1366
1411
|
for (; ; ) {
|
|
@@ -1370,7 +1415,7 @@ function useMergeRequests(params) {
|
|
|
1370
1415
|
await new Promise((r) => setTimeout(r, 1500));
|
|
1371
1416
|
}
|
|
1372
1417
|
}, []);
|
|
1373
|
-
const refresh =
|
|
1418
|
+
const refresh = React6.useCallback(async () => {
|
|
1374
1419
|
if (!appId) {
|
|
1375
1420
|
setIncoming([]);
|
|
1376
1421
|
setOutgoing([]);
|
|
@@ -1409,27 +1454,27 @@ function useMergeRequests(params) {
|
|
|
1409
1454
|
setLoading(false);
|
|
1410
1455
|
}
|
|
1411
1456
|
}, [appId]);
|
|
1412
|
-
|
|
1457
|
+
React6.useEffect(() => {
|
|
1413
1458
|
void refresh();
|
|
1414
1459
|
}, [refresh]);
|
|
1415
|
-
const openMergeRequest =
|
|
1460
|
+
const openMergeRequest = React6.useCallback(async (sourceAppId) => {
|
|
1416
1461
|
const mr = await mergeRequestsRepository.open({ sourceAppId });
|
|
1417
1462
|
await refresh();
|
|
1418
1463
|
return mr;
|
|
1419
1464
|
}, [refresh]);
|
|
1420
|
-
const approve =
|
|
1465
|
+
const approve = React6.useCallback(async (mrId) => {
|
|
1421
1466
|
const mr = await mergeRequestsRepository.update(mrId, { status: "approved" });
|
|
1422
1467
|
await refresh();
|
|
1423
1468
|
const merged = await pollUntilMerged(mrId);
|
|
1424
1469
|
await refresh();
|
|
1425
1470
|
return merged ?? mr;
|
|
1426
1471
|
}, [pollUntilMerged, refresh]);
|
|
1427
|
-
const reject =
|
|
1472
|
+
const reject = React6.useCallback(async (mrId) => {
|
|
1428
1473
|
const mr = await mergeRequestsRepository.update(mrId, { status: "rejected" });
|
|
1429
1474
|
await refresh();
|
|
1430
1475
|
return mr;
|
|
1431
1476
|
}, [refresh]);
|
|
1432
|
-
const toSummary =
|
|
1477
|
+
const toSummary = React6.useCallback((mr) => {
|
|
1433
1478
|
const stats = creatorStatsById[mr.createdBy];
|
|
1434
1479
|
return {
|
|
1435
1480
|
id: mr.id,
|
|
@@ -1445,7 +1490,7 @@ function useMergeRequests(params) {
|
|
|
1445
1490
|
updatedAt: mr.updatedAt
|
|
1446
1491
|
};
|
|
1447
1492
|
}, [creatorStatsById]);
|
|
1448
|
-
const byId =
|
|
1493
|
+
const byId = React6.useMemo(() => {
|
|
1449
1494
|
const all = [...incoming, ...outgoing];
|
|
1450
1495
|
const map = {};
|
|
1451
1496
|
for (const mr of all) map[mr.id] = mr;
|
|
@@ -1463,7 +1508,7 @@ function useMergeRequests(params) {
|
|
|
1463
1508
|
}
|
|
1464
1509
|
|
|
1465
1510
|
// src/studio/hooks/useAttachmentUpload.ts
|
|
1466
|
-
var
|
|
1511
|
+
var React7 = __toESM(require("react"));
|
|
1467
1512
|
|
|
1468
1513
|
// src/data/attachment/remote.ts
|
|
1469
1514
|
var AttachmentRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -1504,9 +1549,9 @@ var attachmentRepository = new AttachmentRepositoryImpl(
|
|
|
1504
1549
|
|
|
1505
1550
|
// src/studio/hooks/useAttachmentUpload.ts
|
|
1506
1551
|
function useAttachmentUpload() {
|
|
1507
|
-
const [uploading, setUploading] =
|
|
1508
|
-
const [error, setError] =
|
|
1509
|
-
const uploadBase64Images =
|
|
1552
|
+
const [uploading, setUploading] = React7.useState(false);
|
|
1553
|
+
const [error, setError] = React7.useState(null);
|
|
1554
|
+
const uploadBase64Images = React7.useCallback(async ({ threadId, appId, dataUrls }) => {
|
|
1510
1555
|
if (!threadId || !appId) return [];
|
|
1511
1556
|
if (!dataUrls || dataUrls.length === 0) return [];
|
|
1512
1557
|
setUploading(true);
|
|
@@ -1540,7 +1585,7 @@ function useAttachmentUpload() {
|
|
|
1540
1585
|
}
|
|
1541
1586
|
|
|
1542
1587
|
// src/studio/hooks/useStudioActions.ts
|
|
1543
|
-
var
|
|
1588
|
+
var React8 = __toESM(require("react"));
|
|
1544
1589
|
|
|
1545
1590
|
// src/data/agent/remote.ts
|
|
1546
1591
|
var AgentRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -1579,12 +1624,12 @@ function useStudioActions({
|
|
|
1579
1624
|
onForkedApp,
|
|
1580
1625
|
uploadAttachments
|
|
1581
1626
|
}) {
|
|
1582
|
-
const [forking, setForking] =
|
|
1583
|
-
const [sending, setSending] =
|
|
1584
|
-
const [error, setError] =
|
|
1627
|
+
const [forking, setForking] = React8.useState(false);
|
|
1628
|
+
const [sending, setSending] = React8.useState(false);
|
|
1629
|
+
const [error, setError] = React8.useState(null);
|
|
1585
1630
|
const isOwner = Boolean(userId && (app == null ? void 0 : app.createdBy) && userId === app.createdBy);
|
|
1586
1631
|
const shouldForkOnEdit = Boolean(userId && app && app.createdBy !== userId);
|
|
1587
|
-
const sendEdit =
|
|
1632
|
+
const sendEdit = React8.useCallback(
|
|
1588
1633
|
async ({ prompt, attachments }) => {
|
|
1589
1634
|
if (!userId || !app) return;
|
|
1590
1635
|
if (!prompt.trim()) return;
|
|
@@ -1647,14 +1692,14 @@ function hasNoOutcomeAfterLastHuman(messages) {
|
|
|
1647
1692
|
}
|
|
1648
1693
|
|
|
1649
1694
|
// src/studio/ui/RuntimeRenderer.tsx
|
|
1650
|
-
var
|
|
1695
|
+
var import_react_native5 = require("react-native");
|
|
1651
1696
|
var import_runtime = require("@comergehq/runtime");
|
|
1652
1697
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1653
1698
|
function RuntimeRenderer({ appKey, bundlePath, renderToken, style }) {
|
|
1654
1699
|
if (!bundlePath) {
|
|
1655
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1700
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.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" }) });
|
|
1656
1701
|
}
|
|
1657
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1702
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native5.View, { style: [{ flex: 1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1658
1703
|
import_runtime.ComergeRuntimeRenderer,
|
|
1659
1704
|
{
|
|
1660
1705
|
appKey,
|
|
@@ -1666,17 +1711,17 @@ function RuntimeRenderer({ appKey, bundlePath, renderToken, style }) {
|
|
|
1666
1711
|
}
|
|
1667
1712
|
|
|
1668
1713
|
// src/studio/ui/StudioOverlay.tsx
|
|
1669
|
-
var
|
|
1670
|
-
var
|
|
1714
|
+
var React38 = __toESM(require("react"));
|
|
1715
|
+
var import_react_native52 = require("react-native");
|
|
1671
1716
|
|
|
1672
1717
|
// src/components/studio-sheet/StudioBottomSheet.tsx
|
|
1673
|
-
var
|
|
1674
|
-
var
|
|
1718
|
+
var React9 = __toESM(require("react"));
|
|
1719
|
+
var import_react_native7 = require("react-native");
|
|
1675
1720
|
var import_bottom_sheet = __toESM(require("@gorhom/bottom-sheet"));
|
|
1676
1721
|
var import_react_native_safe_area_context = require("react-native-safe-area-context");
|
|
1677
1722
|
|
|
1678
1723
|
// src/components/studio-sheet/StudioSheetBackground.tsx
|
|
1679
|
-
var
|
|
1724
|
+
var import_react_native6 = require("react-native");
|
|
1680
1725
|
var import_liquid_glass = require("@callstack/liquid-glass");
|
|
1681
1726
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1682
1727
|
function StudioSheetBackground({
|
|
@@ -1684,7 +1729,7 @@ function StudioSheetBackground({
|
|
|
1684
1729
|
renderBackground
|
|
1685
1730
|
}) {
|
|
1686
1731
|
const theme = useTheme();
|
|
1687
|
-
const radius =
|
|
1732
|
+
const radius = import_react_native6.Platform.OS === "ios" ? 39 : 16;
|
|
1688
1733
|
const fallbackBgColor = theme.scheme === "dark" ? "rgba(11, 8, 15, 0.85)" : "rgba(255, 255, 255, 0.85)";
|
|
1689
1734
|
const secondaryBgBaseColor = theme.scheme === "dark" ? "rgb(24, 24, 27)" : "rgb(173, 173, 173)";
|
|
1690
1735
|
const containerStyle = {
|
|
@@ -1705,7 +1750,7 @@ function StudioSheetBackground({
|
|
|
1705
1750
|
}
|
|
1706
1751
|
),
|
|
1707
1752
|
import_liquid_glass.isLiquidGlassSupported && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1708
|
-
|
|
1753
|
+
import_react_native6.View,
|
|
1709
1754
|
{
|
|
1710
1755
|
style: [
|
|
1711
1756
|
containerStyle,
|
|
@@ -1738,19 +1783,31 @@ function StudioBottomSheet({
|
|
|
1738
1783
|
}) {
|
|
1739
1784
|
const theme = useTheme();
|
|
1740
1785
|
const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
|
|
1741
|
-
const internalSheetRef =
|
|
1786
|
+
const internalSheetRef = React9.useRef(null);
|
|
1742
1787
|
const resolvedSheetRef = sheetRef ?? internalSheetRef;
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1788
|
+
const currentIndexRef = React9.useRef(open ? snapPoints.length - 1 : -1);
|
|
1789
|
+
const lastAppStateRef = React9.useRef(import_react_native7.AppState.currentState);
|
|
1790
|
+
React9.useEffect(() => {
|
|
1791
|
+
const sub = import_react_native7.AppState.addEventListener("change", (state) => {
|
|
1792
|
+
const prev = lastAppStateRef.current;
|
|
1793
|
+
lastAppStateRef.current = state;
|
|
1794
|
+
if (state === "background" || state === "inactive") {
|
|
1795
|
+
import_react_native7.Keyboard.dismiss();
|
|
1796
|
+
return;
|
|
1797
|
+
}
|
|
1798
|
+
if (state !== "active") return;
|
|
1746
1799
|
const sheet = resolvedSheetRef.current;
|
|
1747
|
-
if (!sheet
|
|
1748
|
-
const
|
|
1749
|
-
|
|
1800
|
+
if (!sheet) return;
|
|
1801
|
+
const idx = currentIndexRef.current;
|
|
1802
|
+
if (open && idx >= 0) {
|
|
1803
|
+
import_react_native7.Keyboard.dismiss();
|
|
1804
|
+
requestAnimationFrame(() => sheet.snapToIndex(idx));
|
|
1805
|
+
setTimeout(() => sheet.snapToIndex(idx), 120);
|
|
1806
|
+
}
|
|
1750
1807
|
});
|
|
1751
1808
|
return () => sub.remove();
|
|
1752
|
-
}, [open, resolvedSheetRef
|
|
1753
|
-
|
|
1809
|
+
}, [open, resolvedSheetRef]);
|
|
1810
|
+
React9.useEffect(() => {
|
|
1754
1811
|
const sheet = resolvedSheetRef.current;
|
|
1755
1812
|
if (!sheet) return;
|
|
1756
1813
|
if (open) {
|
|
@@ -1759,8 +1816,9 @@ function StudioBottomSheet({
|
|
|
1759
1816
|
sheet.close();
|
|
1760
1817
|
}
|
|
1761
1818
|
}, [open, resolvedSheetRef, snapPoints.length]);
|
|
1762
|
-
const handleChange =
|
|
1819
|
+
const handleChange = React9.useCallback(
|
|
1763
1820
|
(index) => {
|
|
1821
|
+
currentIndexRef.current = index;
|
|
1764
1822
|
onOpenChange == null ? void 0 : onOpenChange(index >= 0);
|
|
1765
1823
|
},
|
|
1766
1824
|
[onOpenChange]
|
|
@@ -1772,7 +1830,7 @@ function StudioBottomSheet({
|
|
|
1772
1830
|
index: open ? snapPoints.length - 1 : -1,
|
|
1773
1831
|
snapPoints,
|
|
1774
1832
|
enablePanDownToClose: true,
|
|
1775
|
-
keyboardBehavior: "
|
|
1833
|
+
keyboardBehavior: "interactive",
|
|
1776
1834
|
keyboardBlurBehavior: "restore",
|
|
1777
1835
|
android_keyboardInputMode: "adjustResize",
|
|
1778
1836
|
backgroundComponent: (props) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StudioSheetBackground, { ...props, renderBackground: background == null ? void 0 : background.renderBackground }),
|
|
@@ -1781,19 +1839,19 @@ function StudioBottomSheet({
|
|
|
1781
1839
|
handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
|
|
1782
1840
|
onChange: handleChange,
|
|
1783
1841
|
...bottomSheetProps,
|
|
1784
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1842
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native7.View, { style: { flex: 1, overflow: "hidden" }, children })
|
|
1785
1843
|
}
|
|
1786
1844
|
);
|
|
1787
1845
|
}
|
|
1788
1846
|
|
|
1789
1847
|
// src/components/studio-sheet/StudioSheetPager.tsx
|
|
1790
|
-
var
|
|
1791
|
-
var
|
|
1848
|
+
var React10 = __toESM(require("react"));
|
|
1849
|
+
var import_react_native8 = require("react-native");
|
|
1792
1850
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1793
1851
|
function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
1794
|
-
const anim =
|
|
1795
|
-
|
|
1796
|
-
|
|
1852
|
+
const anim = React10.useRef(new import_react_native8.Animated.Value(activePage === "chat" ? 1 : 0)).current;
|
|
1853
|
+
React10.useEffect(() => {
|
|
1854
|
+
import_react_native8.Animated.spring(anim, {
|
|
1797
1855
|
toValue: activePage === "chat" ? 1 : 0,
|
|
1798
1856
|
useNativeDriver: true,
|
|
1799
1857
|
tension: 65,
|
|
@@ -1802,9 +1860,9 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1802
1860
|
}, [activePage, anim]);
|
|
1803
1861
|
const previewTranslateX = anim.interpolate({ inputRange: [0, 1], outputRange: [0, -width] });
|
|
1804
1862
|
const chatTranslateX = anim.interpolate({ inputRange: [0, 1], outputRange: [width, 0] });
|
|
1805
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1863
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native8.Animated.View, { style: [{ flex: 1 }, style], children: [
|
|
1806
1864
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1807
|
-
|
|
1865
|
+
import_react_native8.Animated.View,
|
|
1808
1866
|
{
|
|
1809
1867
|
style: [
|
|
1810
1868
|
{
|
|
@@ -1821,7 +1879,7 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1821
1879
|
}
|
|
1822
1880
|
),
|
|
1823
1881
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1824
|
-
|
|
1882
|
+
import_react_native8.Animated.View,
|
|
1825
1883
|
{
|
|
1826
1884
|
style: [
|
|
1827
1885
|
{
|
|
@@ -1842,7 +1900,7 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1842
1900
|
|
|
1843
1901
|
// src/components/floating-draggable-button/FloatingDraggableButton.tsx
|
|
1844
1902
|
var import_react = require("react");
|
|
1845
|
-
var
|
|
1903
|
+
var import_react_native9 = require("react-native");
|
|
1846
1904
|
var Haptics = __toESM(require("expo-haptics"));
|
|
1847
1905
|
var import_react_native_reanimated = __toESM(require("react-native-reanimated"));
|
|
1848
1906
|
var import_liquid_glass2 = require("@callstack/liquid-glass");
|
|
@@ -1901,7 +1959,7 @@ function FloatingDraggableButton({
|
|
|
1901
1959
|
backgroundColor
|
|
1902
1960
|
}) {
|
|
1903
1961
|
const theme = useTheme();
|
|
1904
|
-
const { width, height } = (0,
|
|
1962
|
+
const { width, height } = (0, import_react_native9.useWindowDimensions)();
|
|
1905
1963
|
const isDanger = variant === "danger";
|
|
1906
1964
|
const onPressRef = (0, import_react.useRef)(onPress);
|
|
1907
1965
|
(0, import_react.useEffect)(() => {
|
|
@@ -2004,7 +2062,7 @@ function FloatingDraggableButton({
|
|
|
2004
2062
|
}
|
|
2005
2063
|
}, [forceShowTrigger, visible, animateIn]);
|
|
2006
2064
|
const panResponder = (0, import_react.useRef)(
|
|
2007
|
-
|
|
2065
|
+
import_react_native9.PanResponder.create({
|
|
2008
2066
|
onStartShouldSetPanResponder: () => true,
|
|
2009
2067
|
onMoveShouldSetPanResponder: () => true,
|
|
2010
2068
|
onPanResponderGrant: () => {
|
|
@@ -2067,24 +2125,24 @@ function FloatingDraggableButton({
|
|
|
2067
2125
|
interactive: true,
|
|
2068
2126
|
effect: "clear",
|
|
2069
2127
|
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2070
|
-
|
|
2128
|
+
import_react_native9.Pressable,
|
|
2071
2129
|
{
|
|
2072
2130
|
onPress: () => {
|
|
2073
2131
|
if (!disabled) animateOut();
|
|
2074
2132
|
},
|
|
2075
2133
|
style: styles.buttonInner,
|
|
2076
2134
|
android_ripple: { color: "rgba(255, 255, 255, 0.3)", borderless: true },
|
|
2077
|
-
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2135
|
+
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.View, {})
|
|
2078
2136
|
}
|
|
2079
2137
|
)
|
|
2080
2138
|
}
|
|
2081
2139
|
) }),
|
|
2082
|
-
badgeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2140
|
+
badgeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.View, { style: [styles.badge, { backgroundColor: theme.colors.danger }], children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.Text, { style: [styles.badgeText, { color: theme.colors.onDanger }], children: badgeCount > 99 ? "99+" : badgeCount }) })
|
|
2083
2141
|
]
|
|
2084
2142
|
}
|
|
2085
2143
|
);
|
|
2086
2144
|
}
|
|
2087
|
-
var styles =
|
|
2145
|
+
var styles = import_react_native9.StyleSheet.create({
|
|
2088
2146
|
floatingButton: {
|
|
2089
2147
|
position: "absolute",
|
|
2090
2148
|
justifyContent: "center",
|
|
@@ -2120,8 +2178,8 @@ var styles = import_react_native8.StyleSheet.create({
|
|
|
2120
2178
|
});
|
|
2121
2179
|
|
|
2122
2180
|
// src/components/overlays/EdgeGlowFrame.tsx
|
|
2123
|
-
var
|
|
2124
|
-
var
|
|
2181
|
+
var React11 = __toESM(require("react"));
|
|
2182
|
+
var import_react_native10 = require("react-native");
|
|
2125
2183
|
var import_expo_linear_gradient = require("expo-linear-gradient");
|
|
2126
2184
|
|
|
2127
2185
|
// src/components/utils/color.ts
|
|
@@ -2163,9 +2221,9 @@ function EdgeGlowFrame({
|
|
|
2163
2221
|
}) {
|
|
2164
2222
|
const theme = useTheme();
|
|
2165
2223
|
const alpha = Math.max(0, Math.min(1, intensity));
|
|
2166
|
-
const anim =
|
|
2167
|
-
|
|
2168
|
-
|
|
2224
|
+
const anim = React11.useRef(new import_react_native10.Animated.Value(visible ? 1 : 0)).current;
|
|
2225
|
+
React11.useEffect(() => {
|
|
2226
|
+
import_react_native10.Animated.timing(anim, {
|
|
2169
2227
|
toValue: visible ? 1 : 0,
|
|
2170
2228
|
duration: 300,
|
|
2171
2229
|
useNativeDriver: true
|
|
@@ -2174,8 +2232,8 @@ function EdgeGlowFrame({
|
|
|
2174
2232
|
const c = baseColor(role, theme);
|
|
2175
2233
|
const strong = withAlpha(c, 0.6 * alpha);
|
|
2176
2234
|
const soft = withAlpha(c, 0.22 * alpha);
|
|
2177
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2178
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2235
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native10.Animated.View, { pointerEvents: "none", style: [{ position: "absolute", inset: 0, opacity: anim }, style], children: [
|
|
2236
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native10.View, { style: { position: "absolute", top: 0, left: 0, right: 0, height: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2179
2237
|
import_expo_linear_gradient.LinearGradient,
|
|
2180
2238
|
{
|
|
2181
2239
|
colors: [strong, soft, "transparent"],
|
|
@@ -2184,7 +2242,7 @@ function EdgeGlowFrame({
|
|
|
2184
2242
|
style: { width: "100%", height: "100%" }
|
|
2185
2243
|
}
|
|
2186
2244
|
) }),
|
|
2187
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2245
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native10.View, { style: { position: "absolute", bottom: 0, left: 0, right: 0, height: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2188
2246
|
import_expo_linear_gradient.LinearGradient,
|
|
2189
2247
|
{
|
|
2190
2248
|
colors: ["transparent", soft, strong],
|
|
@@ -2193,7 +2251,7 @@ function EdgeGlowFrame({
|
|
|
2193
2251
|
style: { width: "100%", height: "100%" }
|
|
2194
2252
|
}
|
|
2195
2253
|
) }),
|
|
2196
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2254
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native10.View, { style: { position: "absolute", top: 0, bottom: 0, left: 0, width: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2197
2255
|
import_expo_linear_gradient.LinearGradient,
|
|
2198
2256
|
{
|
|
2199
2257
|
colors: [strong, soft, "transparent"],
|
|
@@ -2202,7 +2260,7 @@ function EdgeGlowFrame({
|
|
|
2202
2260
|
style: { width: "100%", height: "100%" }
|
|
2203
2261
|
}
|
|
2204
2262
|
) }),
|
|
2205
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2263
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native10.View, { style: { position: "absolute", top: 0, bottom: 0, right: 0, width: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2206
2264
|
import_expo_linear_gradient.LinearGradient,
|
|
2207
2265
|
{
|
|
2208
2266
|
colors: ["transparent", soft, strong],
|
|
@@ -2215,13 +2273,13 @@ function EdgeGlowFrame({
|
|
|
2215
2273
|
}
|
|
2216
2274
|
|
|
2217
2275
|
// src/components/draw/DrawModeOverlay.tsx
|
|
2218
|
-
var
|
|
2219
|
-
var
|
|
2276
|
+
var React14 = __toESM(require("react"));
|
|
2277
|
+
var import_react_native14 = require("react-native");
|
|
2220
2278
|
var import_react_native_view_shot = require("react-native-view-shot");
|
|
2221
2279
|
|
|
2222
2280
|
// src/components/draw/DrawSurface.tsx
|
|
2223
|
-
var
|
|
2224
|
-
var
|
|
2281
|
+
var React12 = __toESM(require("react"));
|
|
2282
|
+
var import_react_native11 = require("react-native");
|
|
2225
2283
|
var import_react_native_svg = __toESM(require("react-native-svg"));
|
|
2226
2284
|
|
|
2227
2285
|
// src/components/draw/strokes.ts
|
|
@@ -2252,25 +2310,25 @@ function DrawSurface({
|
|
|
2252
2310
|
style,
|
|
2253
2311
|
minDistance = 1
|
|
2254
2312
|
}) {
|
|
2255
|
-
const [renderTick, setRenderTick] =
|
|
2256
|
-
const currentPointsRef =
|
|
2257
|
-
const rafRef =
|
|
2258
|
-
const triggerRender =
|
|
2313
|
+
const [renderTick, setRenderTick] = React12.useState(0);
|
|
2314
|
+
const currentPointsRef = React12.useRef([]);
|
|
2315
|
+
const rafRef = React12.useRef(null);
|
|
2316
|
+
const triggerRender = React12.useCallback(() => {
|
|
2259
2317
|
if (rafRef.current !== null) return;
|
|
2260
2318
|
rafRef.current = requestAnimationFrame(() => {
|
|
2261
2319
|
rafRef.current = null;
|
|
2262
2320
|
setRenderTick((n) => n + 1);
|
|
2263
2321
|
});
|
|
2264
2322
|
}, []);
|
|
2265
|
-
|
|
2323
|
+
React12.useEffect(() => () => {
|
|
2266
2324
|
if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);
|
|
2267
2325
|
}, []);
|
|
2268
|
-
const onStart =
|
|
2326
|
+
const onStart = React12.useCallback((e) => {
|
|
2269
2327
|
const { locationX, locationY } = e.nativeEvent;
|
|
2270
2328
|
currentPointsRef.current = [{ x: locationX, y: locationY }];
|
|
2271
2329
|
triggerRender();
|
|
2272
2330
|
}, [triggerRender]);
|
|
2273
|
-
const onMove =
|
|
2331
|
+
const onMove = React12.useCallback((e, _g) => {
|
|
2274
2332
|
const { locationX, locationY } = e.nativeEvent;
|
|
2275
2333
|
const pts = currentPointsRef.current;
|
|
2276
2334
|
if (pts.length > 0) {
|
|
@@ -2283,7 +2341,7 @@ function DrawSurface({
|
|
|
2283
2341
|
currentPointsRef.current = [...pts, { x: locationX, y: locationY }];
|
|
2284
2342
|
triggerRender();
|
|
2285
2343
|
}, [minDistance, triggerRender]);
|
|
2286
|
-
const onEnd =
|
|
2344
|
+
const onEnd = React12.useCallback(() => {
|
|
2287
2345
|
const points = currentPointsRef.current;
|
|
2288
2346
|
if (points.length > 0) {
|
|
2289
2347
|
onAddStroke({ points, color, width: strokeWidth });
|
|
@@ -2291,8 +2349,8 @@ function DrawSurface({
|
|
|
2291
2349
|
currentPointsRef.current = [];
|
|
2292
2350
|
triggerRender();
|
|
2293
2351
|
}, [color, onAddStroke, strokeWidth, triggerRender]);
|
|
2294
|
-
const panResponder =
|
|
2295
|
-
() =>
|
|
2352
|
+
const panResponder = React12.useMemo(
|
|
2353
|
+
() => import_react_native11.PanResponder.create({
|
|
2296
2354
|
onStartShouldSetPanResponder: () => true,
|
|
2297
2355
|
onMoveShouldSetPanResponder: () => true,
|
|
2298
2356
|
onPanResponderGrant: onStart,
|
|
@@ -2304,7 +2362,7 @@ function DrawSurface({
|
|
|
2304
2362
|
);
|
|
2305
2363
|
const currentPath = pointsToSmoothPath(currentPointsRef.current);
|
|
2306
2364
|
void renderTick;
|
|
2307
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2365
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native11.View, { style: [import_react_native11.StyleSheet.absoluteFill, styles2.container, style], ...panResponder.panHandlers, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native_svg.default, { style: import_react_native11.StyleSheet.absoluteFill, width: "100%", height: "100%", children: [
|
|
2308
2366
|
strokes.map((s, idx) => {
|
|
2309
2367
|
const d = pointsToSmoothPath(s.points);
|
|
2310
2368
|
if (!d) return null;
|
|
@@ -2334,15 +2392,15 @@ function DrawSurface({
|
|
|
2334
2392
|
) : null
|
|
2335
2393
|
] }) });
|
|
2336
2394
|
}
|
|
2337
|
-
var styles2 =
|
|
2395
|
+
var styles2 = import_react_native11.StyleSheet.create({
|
|
2338
2396
|
container: {
|
|
2339
2397
|
zIndex: 5
|
|
2340
2398
|
}
|
|
2341
2399
|
});
|
|
2342
2400
|
|
|
2343
2401
|
// src/components/draw/DrawToolbar.tsx
|
|
2344
|
-
var
|
|
2345
|
-
var
|
|
2402
|
+
var React13 = __toESM(require("react"));
|
|
2403
|
+
var import_react_native13 = require("react-native");
|
|
2346
2404
|
var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
|
|
2347
2405
|
var import_lucide_react_native = require("lucide-react-native");
|
|
2348
2406
|
|
|
@@ -2361,7 +2419,7 @@ async function impact(style) {
|
|
|
2361
2419
|
}
|
|
2362
2420
|
|
|
2363
2421
|
// src/components/draw/DrawColorPicker.tsx
|
|
2364
|
-
var
|
|
2422
|
+
var import_react_native12 = require("react-native");
|
|
2365
2423
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2366
2424
|
function DrawColorPicker({
|
|
2367
2425
|
colors,
|
|
@@ -2396,10 +2454,10 @@ function DrawColorPicker({
|
|
|
2396
2454
|
return { ...base, ...selectedStyle, ...whiteStyle };
|
|
2397
2455
|
};
|
|
2398
2456
|
if (!expanded) {
|
|
2399
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2457
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.Pressable, { onPress: onToggle, style: [swatchStyle(selected, true), style] });
|
|
2400
2458
|
}
|
|
2401
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2402
|
-
|
|
2459
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: [{ flexDirection: "row", alignItems: "center", gap: 8 }, style], children: colors.map((c, idx) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2460
|
+
import_react_native12.Pressable,
|
|
2403
2461
|
{
|
|
2404
2462
|
onPress: () => {
|
|
2405
2463
|
onSelect(c);
|
|
@@ -2430,14 +2488,14 @@ function DrawToolbar({
|
|
|
2430
2488
|
style
|
|
2431
2489
|
}) {
|
|
2432
2490
|
const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
|
|
2433
|
-
const { width: screenWidth, height: screenHeight } = (0,
|
|
2434
|
-
const [expanded, setExpanded] =
|
|
2435
|
-
const pos =
|
|
2436
|
-
const start =
|
|
2437
|
-
const currentPos =
|
|
2438
|
-
|
|
2491
|
+
const { width: screenWidth, height: screenHeight } = (0, import_react_native13.useWindowDimensions)();
|
|
2492
|
+
const [expanded, setExpanded] = React13.useState(false);
|
|
2493
|
+
const pos = React13.useRef(new import_react_native13.Animated.ValueXY({ x: screenWidth / 2 - 110, y: -140 })).current;
|
|
2494
|
+
const start = React13.useRef({ x: 0, y: 0 });
|
|
2495
|
+
const currentPos = React13.useRef({ x: 0, y: 0 });
|
|
2496
|
+
React13.useEffect(() => {
|
|
2439
2497
|
if (hidden) return;
|
|
2440
|
-
|
|
2498
|
+
import_react_native13.Animated.spring(pos.y, {
|
|
2441
2499
|
toValue: insets.top + 60,
|
|
2442
2500
|
useNativeDriver: true,
|
|
2443
2501
|
damping: 12,
|
|
@@ -2445,7 +2503,7 @@ function DrawToolbar({
|
|
|
2445
2503
|
mass: 0.8
|
|
2446
2504
|
}).start();
|
|
2447
2505
|
}, [hidden, insets.top, pos.y]);
|
|
2448
|
-
|
|
2506
|
+
React13.useEffect(() => {
|
|
2449
2507
|
const id = pos.addListener((v) => {
|
|
2450
2508
|
currentPos.current = { x: v.x ?? 0, y: v.y ?? 0 };
|
|
2451
2509
|
});
|
|
@@ -2453,7 +2511,7 @@ function DrawToolbar({
|
|
|
2453
2511
|
pos.removeListener(id);
|
|
2454
2512
|
};
|
|
2455
2513
|
}, [pos]);
|
|
2456
|
-
const clamp2 =
|
|
2514
|
+
const clamp2 = React13.useCallback(
|
|
2457
2515
|
(x, y) => {
|
|
2458
2516
|
const minX = 10;
|
|
2459
2517
|
const maxX = Math.max(10, screenWidth - 230);
|
|
@@ -2463,8 +2521,8 @@ function DrawToolbar({
|
|
|
2463
2521
|
},
|
|
2464
2522
|
[insets.top, screenHeight, screenWidth]
|
|
2465
2523
|
);
|
|
2466
|
-
const panResponder =
|
|
2467
|
-
() =>
|
|
2524
|
+
const panResponder = React13.useMemo(
|
|
2525
|
+
() => import_react_native13.PanResponder.create({
|
|
2468
2526
|
onStartShouldSetPanResponder: () => false,
|
|
2469
2527
|
onMoveShouldSetPanResponder: (_e, g) => Math.abs(g.dx) > 5 || Math.abs(g.dy) > 5,
|
|
2470
2528
|
onPanResponderGrant: () => {
|
|
@@ -2476,7 +2534,7 @@ function DrawToolbar({
|
|
|
2476
2534
|
},
|
|
2477
2535
|
onPanResponderRelease: () => {
|
|
2478
2536
|
const next = clamp2(currentPos.current.x, currentPos.current.y);
|
|
2479
|
-
|
|
2537
|
+
import_react_native13.Animated.spring(pos, { toValue: next, useNativeDriver: true }).start();
|
|
2480
2538
|
}
|
|
2481
2539
|
}),
|
|
2482
2540
|
[clamp2, pos]
|
|
@@ -2491,9 +2549,9 @@ function DrawToolbar({
|
|
|
2491
2549
|
children
|
|
2492
2550
|
}) {
|
|
2493
2551
|
const isDisabled = Boolean(disabled) || Boolean(capturingDisabled);
|
|
2494
|
-
const [pressed, setPressed] =
|
|
2552
|
+
const [pressed, setPressed] = React13.useState(false);
|
|
2495
2553
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2496
|
-
|
|
2554
|
+
import_react_native13.View,
|
|
2497
2555
|
{
|
|
2498
2556
|
style: {
|
|
2499
2557
|
width: 28,
|
|
@@ -2505,7 +2563,7 @@ function DrawToolbar({
|
|
|
2505
2563
|
opacity: isDisabled ? 0.5 : pressed ? 0.85 : 1
|
|
2506
2564
|
},
|
|
2507
2565
|
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2508
|
-
|
|
2566
|
+
import_react_native13.Pressable,
|
|
2509
2567
|
{
|
|
2510
2568
|
accessibilityRole: "button",
|
|
2511
2569
|
accessibilityLabel,
|
|
@@ -2522,7 +2580,7 @@ function DrawToolbar({
|
|
|
2522
2580
|
);
|
|
2523
2581
|
}
|
|
2524
2582
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2525
|
-
|
|
2583
|
+
import_react_native13.Animated.View,
|
|
2526
2584
|
{
|
|
2527
2585
|
style: [
|
|
2528
2586
|
{
|
|
@@ -2539,7 +2597,7 @@ function DrawToolbar({
|
|
|
2539
2597
|
],
|
|
2540
2598
|
...panResponder.panHandlers,
|
|
2541
2599
|
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2542
|
-
|
|
2600
|
+
import_react_native13.View,
|
|
2543
2601
|
{
|
|
2544
2602
|
style: {
|
|
2545
2603
|
backgroundColor: "#F43F5E",
|
|
@@ -2547,7 +2605,7 @@ function DrawToolbar({
|
|
|
2547
2605
|
padding: 12,
|
|
2548
2606
|
minWidth: 220
|
|
2549
2607
|
},
|
|
2550
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2608
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: { flexDirection: "row", alignItems: "center", gap: 8 }, children: [
|
|
2551
2609
|
renderDragHandle ? renderDragHandle() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react_native.GripVertical, { size: 20, color: "rgba(255, 255, 255, 0.6)" }),
|
|
2552
2610
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2553
2611
|
DrawColorPicker,
|
|
@@ -2565,7 +2623,7 @@ function DrawToolbar({
|
|
|
2565
2623
|
}
|
|
2566
2624
|
}
|
|
2567
2625
|
),
|
|
2568
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2626
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native13.View, { style: { width: 1, height: 20, backgroundColor: "rgba(255, 255, 255, 0.3)", marginHorizontal: 4 } }),
|
|
2569
2627
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2570
2628
|
CircleActionButton,
|
|
2571
2629
|
{
|
|
@@ -2603,7 +2661,7 @@ function DrawToolbar({
|
|
|
2603
2661
|
void impact("medium");
|
|
2604
2662
|
onDone();
|
|
2605
2663
|
},
|
|
2606
|
-
children: capturing ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2664
|
+
children: capturing ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native13.ActivityIndicator, { color: "#FFFFFF", size: "small" }) : renderDoneIcon ? renderDoneIcon() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react_native.Check, { size: 16, color: "#FFFFFF" })
|
|
2607
2665
|
}
|
|
2608
2666
|
)
|
|
2609
2667
|
] })
|
|
@@ -2629,7 +2687,7 @@ function DrawModeOverlay({
|
|
|
2629
2687
|
renderDragHandle
|
|
2630
2688
|
}) {
|
|
2631
2689
|
const theme = useTheme();
|
|
2632
|
-
const defaultPalette =
|
|
2690
|
+
const defaultPalette = React14.useMemo(
|
|
2633
2691
|
() => [
|
|
2634
2692
|
"#EF4444",
|
|
2635
2693
|
// Red
|
|
@@ -2647,11 +2705,11 @@ function DrawModeOverlay({
|
|
|
2647
2705
|
[]
|
|
2648
2706
|
);
|
|
2649
2707
|
const colors = palette && palette.length > 0 ? palette : defaultPalette;
|
|
2650
|
-
const [selectedColor, setSelectedColor] =
|
|
2651
|
-
const [strokes, setStrokes] =
|
|
2652
|
-
const [capturing, setCapturing] =
|
|
2653
|
-
const [hideUi, setHideUi] =
|
|
2654
|
-
|
|
2708
|
+
const [selectedColor, setSelectedColor] = React14.useState(colors[0] ?? "#EF4444");
|
|
2709
|
+
const [strokes, setStrokes] = React14.useState([]);
|
|
2710
|
+
const [capturing, setCapturing] = React14.useState(false);
|
|
2711
|
+
const [hideUi, setHideUi] = React14.useState(false);
|
|
2712
|
+
React14.useEffect(() => {
|
|
2655
2713
|
if (!visible) return;
|
|
2656
2714
|
setStrokes([]);
|
|
2657
2715
|
setSelectedColor(colors[0] ?? "#EF4444");
|
|
@@ -2659,14 +2717,14 @@ function DrawModeOverlay({
|
|
|
2659
2717
|
setHideUi(false);
|
|
2660
2718
|
}, [colors, visible]);
|
|
2661
2719
|
const canUndo = strokes.length > 0;
|
|
2662
|
-
const handleUndo =
|
|
2720
|
+
const handleUndo = React14.useCallback(() => {
|
|
2663
2721
|
setStrokes((prev) => prev.slice(0, -1));
|
|
2664
2722
|
}, []);
|
|
2665
|
-
const handleCancel =
|
|
2723
|
+
const handleCancel = React14.useCallback(() => {
|
|
2666
2724
|
setStrokes([]);
|
|
2667
2725
|
onCancel();
|
|
2668
2726
|
}, [onCancel]);
|
|
2669
|
-
const handleDone =
|
|
2727
|
+
const handleDone = React14.useCallback(async () => {
|
|
2670
2728
|
if (!captureTargetRef.current || capturing) return;
|
|
2671
2729
|
try {
|
|
2672
2730
|
setCapturing(true);
|
|
@@ -2688,7 +2746,7 @@ function DrawModeOverlay({
|
|
|
2688
2746
|
}
|
|
2689
2747
|
}, [captureTargetRef, capturing, onCapture]);
|
|
2690
2748
|
if (!visible) return null;
|
|
2691
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2749
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native14.View, { style: [import_react_native14.StyleSheet.absoluteFill, styles3.root, style], pointerEvents: "box-none", children: [
|
|
2692
2750
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(EdgeGlowFrame, { visible: !hideUi, role: "danger", thickness: 50, intensity: 1 }),
|
|
2693
2751
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2694
2752
|
DrawSurface,
|
|
@@ -2719,32 +2777,32 @@ function DrawModeOverlay({
|
|
|
2719
2777
|
)
|
|
2720
2778
|
] });
|
|
2721
2779
|
}
|
|
2722
|
-
var styles3 =
|
|
2780
|
+
var styles3 = import_react_native14.StyleSheet.create({
|
|
2723
2781
|
root: {
|
|
2724
2782
|
zIndex: 9999
|
|
2725
2783
|
}
|
|
2726
2784
|
});
|
|
2727
2785
|
|
|
2728
2786
|
// src/components/comments/AppCommentsSheet.tsx
|
|
2729
|
-
var
|
|
2730
|
-
var
|
|
2787
|
+
var React21 = __toESM(require("react"));
|
|
2788
|
+
var import_react_native20 = require("react-native");
|
|
2731
2789
|
var import_bottom_sheet3 = require("@gorhom/bottom-sheet");
|
|
2732
2790
|
var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
|
|
2733
2791
|
var import_liquid_glass4 = require("@callstack/liquid-glass");
|
|
2734
2792
|
var import_lucide_react_native4 = require("lucide-react-native");
|
|
2735
2793
|
|
|
2736
2794
|
// src/components/chat/ChatComposer.tsx
|
|
2737
|
-
var
|
|
2738
|
-
var
|
|
2795
|
+
var React16 = __toESM(require("react"));
|
|
2796
|
+
var import_react_native16 = require("react-native");
|
|
2739
2797
|
var import_liquid_glass3 = require("@callstack/liquid-glass");
|
|
2740
2798
|
var import_lucide_react_native3 = require("lucide-react-native");
|
|
2741
2799
|
|
|
2742
2800
|
// src/components/chat/MultilineTextInput.tsx
|
|
2743
|
-
var
|
|
2744
|
-
var
|
|
2801
|
+
var React15 = __toESM(require("react"));
|
|
2802
|
+
var import_react_native15 = require("react-native");
|
|
2745
2803
|
var import_bottom_sheet2 = require("@gorhom/bottom-sheet");
|
|
2746
2804
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2747
|
-
var MultilineTextInput =
|
|
2805
|
+
var MultilineTextInput = React15.forwardRef(function MultilineTextInput2({ useBottomSheetTextInput = false, placeholder, placeholderTextColor, style, ...props }, ref) {
|
|
2748
2806
|
const theme = useTheme();
|
|
2749
2807
|
const baseStyle = {
|
|
2750
2808
|
minHeight: 44,
|
|
@@ -2764,7 +2822,7 @@ var MultilineTextInput = React14.forwardRef(function MultilineTextInput2({ useBo
|
|
|
2764
2822
|
style: [baseStyle, style],
|
|
2765
2823
|
textAlignVertical: "top"
|
|
2766
2824
|
};
|
|
2767
|
-
return useBottomSheetTextInput ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_bottom_sheet2.BottomSheetTextInput, { ref, ...commonProps }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2825
|
+
return useBottomSheetTextInput ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_bottom_sheet2.BottomSheetTextInput, { ref, ...commonProps }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native15.TextInput, { ref, ...commonProps });
|
|
2768
2826
|
});
|
|
2769
2827
|
|
|
2770
2828
|
// src/components/icons/StudioIcons.tsx
|
|
@@ -2816,10 +2874,10 @@ function AspectRatioThumbnail({
|
|
|
2816
2874
|
onRemove,
|
|
2817
2875
|
renderRemoveIcon
|
|
2818
2876
|
}) {
|
|
2819
|
-
const [aspectRatio, setAspectRatio] =
|
|
2820
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2821
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2822
|
-
|
|
2877
|
+
const [aspectRatio, setAspectRatio] = React16.useState(1);
|
|
2878
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: { height: THUMBNAIL_HEIGHT, aspectRatio, position: "relative" }, children: [
|
|
2879
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.View, { style: { flex: 1, borderRadius: 8, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2880
|
+
import_react_native16.Image,
|
|
2823
2881
|
{
|
|
2824
2882
|
source: { uri },
|
|
2825
2883
|
style: { width: "100%", height: "100%" },
|
|
@@ -2832,7 +2890,7 @@ function AspectRatioThumbnail({
|
|
|
2832
2890
|
}
|
|
2833
2891
|
) }),
|
|
2834
2892
|
onRemove ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2835
|
-
|
|
2893
|
+
import_react_native16.Pressable,
|
|
2836
2894
|
{
|
|
2837
2895
|
style: {
|
|
2838
2896
|
position: "absolute",
|
|
@@ -2858,6 +2916,7 @@ function ChatComposer({
|
|
|
2858
2916
|
onChangeValue,
|
|
2859
2917
|
placeholder = "Describe the idea you want to build",
|
|
2860
2918
|
disabled = false,
|
|
2919
|
+
sendDisabled = false,
|
|
2861
2920
|
sending = false,
|
|
2862
2921
|
autoFocus = false,
|
|
2863
2922
|
onSend,
|
|
@@ -2872,19 +2931,19 @@ function ChatComposer({
|
|
|
2872
2931
|
style
|
|
2873
2932
|
}) {
|
|
2874
2933
|
const theme = useTheme();
|
|
2875
|
-
const [internal, setInternal] =
|
|
2934
|
+
const [internal, setInternal] = React16.useState("");
|
|
2876
2935
|
const text = value ?? internal;
|
|
2877
2936
|
const setText = onChangeValue ?? setInternal;
|
|
2878
2937
|
const hasAttachments = attachments.length > 0;
|
|
2879
2938
|
const hasText = text.trim().length > 0;
|
|
2880
2939
|
const composerMinHeight = hasAttachments ? THUMBNAIL_HEIGHT + 44 + 24 : 44;
|
|
2881
|
-
const isButtonDisabled = sending || disabled;
|
|
2882
|
-
const maxInputHeight =
|
|
2883
|
-
const shakeAnim =
|
|
2884
|
-
const [sendPressed, setSendPressed] =
|
|
2885
|
-
const inputRef =
|
|
2886
|
-
const prevAutoFocusRef =
|
|
2887
|
-
|
|
2940
|
+
const isButtonDisabled = sending || disabled || sendDisabled;
|
|
2941
|
+
const maxInputHeight = React16.useMemo(() => import_react_native16.Dimensions.get("window").height * 0.5, []);
|
|
2942
|
+
const shakeAnim = React16.useRef(new import_react_native16.Animated.Value(0)).current;
|
|
2943
|
+
const [sendPressed, setSendPressed] = React16.useState(false);
|
|
2944
|
+
const inputRef = React16.useRef(null);
|
|
2945
|
+
const prevAutoFocusRef = React16.useRef(false);
|
|
2946
|
+
React16.useEffect(() => {
|
|
2888
2947
|
const shouldFocus = autoFocus && !prevAutoFocusRef.current && !disabled && !sending;
|
|
2889
2948
|
prevAutoFocusRef.current = autoFocus;
|
|
2890
2949
|
if (!shouldFocus) return;
|
|
@@ -2894,17 +2953,17 @@ function ChatComposer({
|
|
|
2894
2953
|
}, 75);
|
|
2895
2954
|
return () => clearTimeout(t);
|
|
2896
2955
|
}, [autoFocus, disabled, sending]);
|
|
2897
|
-
const triggerShake =
|
|
2956
|
+
const triggerShake = React16.useCallback(() => {
|
|
2898
2957
|
shakeAnim.setValue(0);
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2958
|
+
import_react_native16.Animated.sequence([
|
|
2959
|
+
import_react_native16.Animated.timing(shakeAnim, { toValue: 10, duration: 50, useNativeDriver: true }),
|
|
2960
|
+
import_react_native16.Animated.timing(shakeAnim, { toValue: -10, duration: 50, useNativeDriver: true }),
|
|
2961
|
+
import_react_native16.Animated.timing(shakeAnim, { toValue: 10, duration: 50, useNativeDriver: true }),
|
|
2962
|
+
import_react_native16.Animated.timing(shakeAnim, { toValue: -10, duration: 50, useNativeDriver: true }),
|
|
2963
|
+
import_react_native16.Animated.timing(shakeAnim, { toValue: 0, duration: 50, useNativeDriver: true })
|
|
2905
2964
|
]).start();
|
|
2906
2965
|
}, [shakeAnim]);
|
|
2907
|
-
const handleSend =
|
|
2966
|
+
const handleSend = React16.useCallback(async () => {
|
|
2908
2967
|
if (isButtonDisabled) return;
|
|
2909
2968
|
if (!hasText) {
|
|
2910
2969
|
triggerShake();
|
|
@@ -2917,12 +2976,12 @@ function ChatComposer({
|
|
|
2917
2976
|
const textareaBgColor = theme.scheme === "dark" ? "#18181B" : "#F6F6F6";
|
|
2918
2977
|
const placeholderTextColor = theme.scheme === "dark" ? "#A1A1AA" : "#71717A";
|
|
2919
2978
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2920
|
-
|
|
2979
|
+
import_react_native16.View,
|
|
2921
2980
|
{
|
|
2922
2981
|
style: [{ paddingHorizontal: 16, paddingBottom: 12, paddingTop: 8 }, style],
|
|
2923
2982
|
onLayout: (e) => onLayout == null ? void 0 : onLayout({ height: e.nativeEvent.layout.height }),
|
|
2924
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2925
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2983
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: { flexDirection: "row", alignItems: "flex-end", gap: 8 }, children: [
|
|
2984
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.Animated.View, { style: { flex: 1, transform: [{ translateX: shakeAnim }] }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2926
2985
|
import_liquid_glass3.LiquidGlassView,
|
|
2927
2986
|
{
|
|
2928
2987
|
style: [
|
|
@@ -2935,7 +2994,7 @@ function ChatComposer({
|
|
|
2935
2994
|
effect: "clear",
|
|
2936
2995
|
children: [
|
|
2937
2996
|
hasAttachments ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2938
|
-
|
|
2997
|
+
import_react_native16.ScrollView,
|
|
2939
2998
|
{
|
|
2940
2999
|
horizontal: true,
|
|
2941
3000
|
showsHorizontalScrollIndicator: false,
|
|
@@ -2952,7 +3011,7 @@ function ChatComposer({
|
|
|
2952
3011
|
`attachment-${index}`
|
|
2953
3012
|
)),
|
|
2954
3013
|
onAddAttachment ? renderAddAttachment ? renderAddAttachment() : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2955
|
-
|
|
3014
|
+
import_react_native16.Pressable,
|
|
2956
3015
|
{
|
|
2957
3016
|
style: {
|
|
2958
3017
|
height: THUMBNAIL_HEIGHT,
|
|
@@ -3004,7 +3063,7 @@ function ChatComposer({
|
|
|
3004
3063
|
interactive: true,
|
|
3005
3064
|
effect: "clear",
|
|
3006
3065
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3007
|
-
|
|
3066
|
+
import_react_native16.View,
|
|
3008
3067
|
{
|
|
3009
3068
|
style: {
|
|
3010
3069
|
width: 44,
|
|
@@ -3015,7 +3074,7 @@ function ChatComposer({
|
|
|
3015
3074
|
opacity: isButtonDisabled ? 0.6 : sendPressed ? 0.9 : 1
|
|
3016
3075
|
},
|
|
3017
3076
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3018
|
-
|
|
3077
|
+
import_react_native16.Pressable,
|
|
3019
3078
|
{
|
|
3020
3079
|
accessibilityRole: "button",
|
|
3021
3080
|
accessibilityLabel: "Send",
|
|
@@ -3024,7 +3083,7 @@ function ChatComposer({
|
|
|
3024
3083
|
onPressIn: () => setSendPressed(true),
|
|
3025
3084
|
onPressOut: () => setSendPressed(false),
|
|
3026
3085
|
style: { flex: 1, alignItems: "center", justifyContent: "center" },
|
|
3027
|
-
children: sending ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3086
|
+
children: sending ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.ActivityIndicator, {}) : renderSendIcon ? renderSendIcon() : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconChevronRight, { size: 20, colorToken: "onPrimary" })
|
|
3028
3087
|
}
|
|
3029
3088
|
)
|
|
3030
3089
|
}
|
|
@@ -3037,11 +3096,11 @@ function ChatComposer({
|
|
|
3037
3096
|
}
|
|
3038
3097
|
|
|
3039
3098
|
// src/components/comments/CommentRow.tsx
|
|
3040
|
-
var
|
|
3041
|
-
var
|
|
3099
|
+
var React17 = __toESM(require("react"));
|
|
3100
|
+
var import_react_native18 = require("react-native");
|
|
3042
3101
|
|
|
3043
3102
|
// src/components/primitives/Avatar.tsx
|
|
3044
|
-
var
|
|
3103
|
+
var import_react_native17 = require("react-native");
|
|
3045
3104
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3046
3105
|
function initialsFrom(name) {
|
|
3047
3106
|
var _a, _b;
|
|
@@ -3061,7 +3120,7 @@ function Avatar({
|
|
|
3061
3120
|
const radius = size / 2;
|
|
3062
3121
|
const fallbackBg = fallbackBackgroundColor ?? theme.colors.neutral;
|
|
3063
3122
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3064
|
-
|
|
3123
|
+
import_react_native17.View,
|
|
3065
3124
|
{
|
|
3066
3125
|
style: [
|
|
3067
3126
|
{
|
|
@@ -3076,7 +3135,7 @@ function Avatar({
|
|
|
3076
3135
|
style
|
|
3077
3136
|
],
|
|
3078
3137
|
children: uri ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3079
|
-
|
|
3138
|
+
import_react_native17.Image,
|
|
3080
3139
|
{
|
|
3081
3140
|
source: { uri },
|
|
3082
3141
|
style: [{ width: size, height: size }, imageStyle],
|
|
@@ -3109,9 +3168,9 @@ function formatTimeAgo(iso) {
|
|
|
3109
3168
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3110
3169
|
function CommentRow({ comment, showDivider }) {
|
|
3111
3170
|
const theme = useTheme();
|
|
3112
|
-
const [authorName, setAuthorName] =
|
|
3113
|
-
const [authorAvatar, setAuthorAvatar] =
|
|
3114
|
-
|
|
3171
|
+
const [authorName, setAuthorName] = React17.useState(null);
|
|
3172
|
+
const [authorAvatar, setAuthorAvatar] = React17.useState(null);
|
|
3173
|
+
React17.useEffect(() => {
|
|
3115
3174
|
let cancelled = false;
|
|
3116
3175
|
(async () => {
|
|
3117
3176
|
try {
|
|
@@ -3127,7 +3186,7 @@ function CommentRow({ comment, showDivider }) {
|
|
|
3127
3186
|
};
|
|
3128
3187
|
}, [comment.authorId]);
|
|
3129
3188
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
3130
|
-
|
|
3189
|
+
import_react_native18.View,
|
|
3131
3190
|
{
|
|
3132
3191
|
style: {
|
|
3133
3192
|
flexDirection: "row",
|
|
@@ -3138,8 +3197,8 @@ function CommentRow({ comment, showDivider }) {
|
|
|
3138
3197
|
},
|
|
3139
3198
|
children: [
|
|
3140
3199
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Avatar, { size: 32, uri: authorAvatar, name: authorName ?? comment.authorId, style: { marginTop: 6 } }),
|
|
3141
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
3142
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
3200
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native18.View, { style: { flex: 1, minWidth: 0, gap: 4 }, children: [
|
|
3201
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native18.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.sm }, children: [
|
|
3143
3202
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { style: { fontSize: 14, lineHeight: 18, fontWeight: theme.typography.fontWeight.bold, color: theme.colors.text }, children: authorName ?? "Unknown User" }),
|
|
3144
3203
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, children: formatTimeAgo(comment.createdAt) })
|
|
3145
3204
|
] }),
|
|
@@ -3151,7 +3210,7 @@ function CommentRow({ comment, showDivider }) {
|
|
|
3151
3210
|
}
|
|
3152
3211
|
|
|
3153
3212
|
// src/components/comments/useAppComments.ts
|
|
3154
|
-
var
|
|
3213
|
+
var React18 = __toESM(require("react"));
|
|
3155
3214
|
|
|
3156
3215
|
// src/data/comments/remote.ts
|
|
3157
3216
|
var AppCommentsRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -3223,18 +3282,18 @@ var appCommentsRepository = new AppCommentsRepositoryImpl(appCommentsRemoteDataS
|
|
|
3223
3282
|
|
|
3224
3283
|
// src/components/comments/useAppComments.ts
|
|
3225
3284
|
function useAppComments(appId) {
|
|
3226
|
-
const [comments, setComments] =
|
|
3227
|
-
const [loading, setLoading] =
|
|
3228
|
-
const [sending, setSending] =
|
|
3229
|
-
const [error, setError] =
|
|
3230
|
-
const sortByCreatedAtAsc =
|
|
3285
|
+
const [comments, setComments] = React18.useState([]);
|
|
3286
|
+
const [loading, setLoading] = React18.useState(false);
|
|
3287
|
+
const [sending, setSending] = React18.useState(false);
|
|
3288
|
+
const [error, setError] = React18.useState(null);
|
|
3289
|
+
const sortByCreatedAtAsc = React18.useCallback((items) => {
|
|
3231
3290
|
return [...items].sort((a, b) => {
|
|
3232
3291
|
const at = a.createdAt ? new Date(a.createdAt).getTime() : 0;
|
|
3233
3292
|
const bt = b.createdAt ? new Date(b.createdAt).getTime() : 0;
|
|
3234
3293
|
return at - bt;
|
|
3235
3294
|
});
|
|
3236
3295
|
}, []);
|
|
3237
|
-
const refresh =
|
|
3296
|
+
const refresh = React18.useCallback(async () => {
|
|
3238
3297
|
if (!appId) {
|
|
3239
3298
|
setComments([]);
|
|
3240
3299
|
return;
|
|
@@ -3251,10 +3310,10 @@ function useAppComments(appId) {
|
|
|
3251
3310
|
setLoading(false);
|
|
3252
3311
|
}
|
|
3253
3312
|
}, [appId, sortByCreatedAtAsc]);
|
|
3254
|
-
|
|
3313
|
+
React18.useEffect(() => {
|
|
3255
3314
|
void refresh();
|
|
3256
3315
|
}, [refresh]);
|
|
3257
|
-
const create =
|
|
3316
|
+
const create = React18.useCallback(
|
|
3258
3317
|
async (text) => {
|
|
3259
3318
|
if (!appId) return;
|
|
3260
3319
|
const trimmed = text.trim();
|
|
@@ -3277,11 +3336,11 @@ function useAppComments(appId) {
|
|
|
3277
3336
|
}
|
|
3278
3337
|
|
|
3279
3338
|
// src/components/comments/useAppDetails.ts
|
|
3280
|
-
var
|
|
3339
|
+
var React19 = __toESM(require("react"));
|
|
3281
3340
|
function useAppDetails(appId) {
|
|
3282
|
-
const [app, setApp] =
|
|
3283
|
-
const [loading, setLoading] =
|
|
3284
|
-
|
|
3341
|
+
const [app, setApp] = React19.useState(null);
|
|
3342
|
+
const [loading, setLoading] = React19.useState(false);
|
|
3343
|
+
React19.useEffect(() => {
|
|
3285
3344
|
if (!appId) {
|
|
3286
3345
|
setApp(null);
|
|
3287
3346
|
return;
|
|
@@ -3306,25 +3365,30 @@ function useAppDetails(appId) {
|
|
|
3306
3365
|
}
|
|
3307
3366
|
|
|
3308
3367
|
// src/components/comments/useIosKeyboardSnapFix.ts
|
|
3309
|
-
var
|
|
3310
|
-
var
|
|
3311
|
-
function useIosKeyboardSnapFix(sheetRef) {
|
|
3312
|
-
const [keyboardVisible, setKeyboardVisible] =
|
|
3313
|
-
|
|
3314
|
-
if (
|
|
3315
|
-
const show =
|
|
3316
|
-
const hide =
|
|
3368
|
+
var React20 = __toESM(require("react"));
|
|
3369
|
+
var import_react_native19 = require("react-native");
|
|
3370
|
+
function useIosKeyboardSnapFix(sheetRef, options) {
|
|
3371
|
+
const [keyboardVisible, setKeyboardVisible] = React20.useState(false);
|
|
3372
|
+
React20.useEffect(() => {
|
|
3373
|
+
if (import_react_native19.Platform.OS !== "ios") return;
|
|
3374
|
+
const show = import_react_native19.Keyboard.addListener("keyboardWillShow", () => setKeyboardVisible(true));
|
|
3375
|
+
const hide = import_react_native19.Keyboard.addListener("keyboardWillHide", () => {
|
|
3376
|
+
var _a;
|
|
3317
3377
|
setKeyboardVisible(false);
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3378
|
+
const target = (options == null ? void 0 : options.targetIndex) ?? 1;
|
|
3379
|
+
const current = ((_a = options == null ? void 0 : options.getCurrentIndex) == null ? void 0 : _a.call(options)) ?? null;
|
|
3380
|
+
if (current === target) {
|
|
3381
|
+
setTimeout(() => {
|
|
3382
|
+
var _a2, _b;
|
|
3383
|
+
return (_b = (_a2 = sheetRef.current) == null ? void 0 : _a2.snapToIndex) == null ? void 0 : _b.call(_a2, target);
|
|
3384
|
+
}, 10);
|
|
3385
|
+
}
|
|
3322
3386
|
});
|
|
3323
3387
|
return () => {
|
|
3324
3388
|
show.remove();
|
|
3325
3389
|
hide.remove();
|
|
3326
3390
|
};
|
|
3327
|
-
}, [sheetRef]);
|
|
3391
|
+
}, [options == null ? void 0 : options.getCurrentIndex, options == null ? void 0 : options.targetIndex, sheetRef]);
|
|
3328
3392
|
return { keyboardVisible };
|
|
3329
3393
|
}
|
|
3330
3394
|
|
|
@@ -3333,12 +3397,16 @@ var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
|
3333
3397
|
function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
3334
3398
|
const theme = useTheme();
|
|
3335
3399
|
const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
|
|
3336
|
-
const sheetRef =
|
|
3337
|
-
const snapPoints =
|
|
3400
|
+
const sheetRef = React21.useRef(null);
|
|
3401
|
+
const snapPoints = React21.useMemo(() => ["50%", "90%"], []);
|
|
3402
|
+
const currentIndexRef = React21.useRef(1);
|
|
3338
3403
|
const { comments, loading, sending, error, create, refresh } = useAppComments(appId);
|
|
3339
3404
|
const { app, loading: loadingApp } = useAppDetails(appId);
|
|
3340
|
-
const { keyboardVisible } = useIosKeyboardSnapFix(sheetRef
|
|
3341
|
-
|
|
3405
|
+
const { keyboardVisible } = useIosKeyboardSnapFix(sheetRef, {
|
|
3406
|
+
getCurrentIndex: () => currentIndexRef.current,
|
|
3407
|
+
targetIndex: 1
|
|
3408
|
+
});
|
|
3409
|
+
React21.useEffect(() => {
|
|
3342
3410
|
var _a, _b;
|
|
3343
3411
|
if (appId) {
|
|
3344
3412
|
(_a = sheetRef.current) == null ? void 0 : _a.present();
|
|
@@ -3347,21 +3415,22 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3347
3415
|
(_b = sheetRef.current) == null ? void 0 : _b.dismiss();
|
|
3348
3416
|
}
|
|
3349
3417
|
}, [appId, refresh]);
|
|
3350
|
-
|
|
3418
|
+
React21.useEffect(() => {
|
|
3351
3419
|
if (!appId) return;
|
|
3352
3420
|
onCountChange == null ? void 0 : onCountChange(comments.length);
|
|
3353
3421
|
}, [appId, comments.length, onCountChange]);
|
|
3354
|
-
const renderBackdrop =
|
|
3422
|
+
const renderBackdrop = React21.useCallback(
|
|
3355
3423
|
(props) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_bottom_sheet3.BottomSheetBackdrop, { ...props, disappearsOnIndex: -1, appearsOnIndex: 0, opacity: 0.5 }),
|
|
3356
3424
|
[]
|
|
3357
3425
|
);
|
|
3358
|
-
const handleChange =
|
|
3426
|
+
const handleChange = React21.useCallback(
|
|
3359
3427
|
(index) => {
|
|
3428
|
+
currentIndexRef.current = index;
|
|
3360
3429
|
if (index === -1) onClose();
|
|
3361
3430
|
},
|
|
3362
3431
|
[onClose]
|
|
3363
3432
|
);
|
|
3364
|
-
const handlePlay =
|
|
3433
|
+
const handlePlay = React21.useCallback(async () => {
|
|
3365
3434
|
var _a;
|
|
3366
3435
|
if (!appId) return;
|
|
3367
3436
|
(_a = sheetRef.current) == null ? void 0 : _a.dismiss();
|
|
@@ -3379,17 +3448,17 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3379
3448
|
onChange: handleChange,
|
|
3380
3449
|
backgroundStyle: {
|
|
3381
3450
|
backgroundColor: theme.scheme === "dark" ? "#0B080F" : "#FFFFFF",
|
|
3382
|
-
borderTopLeftRadius:
|
|
3383
|
-
borderTopRightRadius:
|
|
3451
|
+
borderTopLeftRadius: import_react_native20.Platform.OS === "ios" ? 39 : 16,
|
|
3452
|
+
borderTopRightRadius: import_react_native20.Platform.OS === "ios" ? 39 : 16
|
|
3384
3453
|
},
|
|
3385
3454
|
handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
|
|
3386
3455
|
keyboardBehavior: "interactive",
|
|
3387
3456
|
keyboardBlurBehavior: "restore",
|
|
3388
3457
|
android_keyboardInputMode: "adjustResize",
|
|
3389
3458
|
topInset: insets.top,
|
|
3390
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3459
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native20.View, { style: { flex: 1 }, children: [
|
|
3391
3460
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3392
|
-
|
|
3461
|
+
import_react_native20.View,
|
|
3393
3462
|
{
|
|
3394
3463
|
style: {
|
|
3395
3464
|
flexDirection: "row",
|
|
@@ -3425,7 +3494,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3425
3494
|
interactive: true,
|
|
3426
3495
|
effect: "clear",
|
|
3427
3496
|
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3428
|
-
|
|
3497
|
+
import_react_native20.View,
|
|
3429
3498
|
{
|
|
3430
3499
|
style: {
|
|
3431
3500
|
width: 32,
|
|
@@ -3437,7 +3506,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3437
3506
|
opacity: appId ? 1 : 0.5
|
|
3438
3507
|
},
|
|
3439
3508
|
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3440
|
-
|
|
3509
|
+
import_react_native20.Pressable,
|
|
3441
3510
|
{
|
|
3442
3511
|
disabled: !appId,
|
|
3443
3512
|
onPress: () => void handlePlay(),
|
|
@@ -3472,13 +3541,13 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3472
3541
|
},
|
|
3473
3542
|
keyboardShouldPersistTaps: "handled",
|
|
3474
3543
|
children: [
|
|
3475
|
-
loading && comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3544
|
+
loading && comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native20.View, { style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native20.ActivityIndicator, {}) }) : comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native20.View, { style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { variant: "bodyMuted", style: { textAlign: "center" }, children: "No comments yet" }) }) : comments.map((c, idx) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(CommentRow, { comment: c, showDivider: idx < comments.length - 1 }, c.id)),
|
|
3476
3545
|
error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { variant: "captionMuted", style: { marginTop: theme.spacing.lg }, children: "Failed to load comments." }) : null
|
|
3477
3546
|
]
|
|
3478
3547
|
}
|
|
3479
3548
|
),
|
|
3480
3549
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3481
|
-
|
|
3550
|
+
import_react_native20.View,
|
|
3482
3551
|
{
|
|
3483
3552
|
style: {
|
|
3484
3553
|
position: "absolute",
|
|
@@ -3487,7 +3556,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3487
3556
|
bottom: 0,
|
|
3488
3557
|
paddingHorizontal: theme.spacing.lg,
|
|
3489
3558
|
paddingTop: theme.spacing.sm,
|
|
3490
|
-
paddingBottom:
|
|
3559
|
+
paddingBottom: import_react_native20.Platform.OS === "ios" ? keyboardVisible ? theme.spacing.lg : insets.bottom : insets.bottom + 10,
|
|
3491
3560
|
borderTopWidth: 1,
|
|
3492
3561
|
borderTopColor: withAlpha(theme.colors.border, 0.1),
|
|
3493
3562
|
backgroundColor: withAlpha(theme.colors.background, 0.8)
|
|
@@ -3501,7 +3570,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3501
3570
|
useBottomSheetTextInput: true,
|
|
3502
3571
|
onSend: async (text) => {
|
|
3503
3572
|
await create(text);
|
|
3504
|
-
|
|
3573
|
+
import_react_native20.Keyboard.dismiss();
|
|
3505
3574
|
}
|
|
3506
3575
|
}
|
|
3507
3576
|
)
|
|
@@ -3513,16 +3582,16 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3513
3582
|
}
|
|
3514
3583
|
|
|
3515
3584
|
// src/studio/ui/PreviewPanel.tsx
|
|
3516
|
-
var
|
|
3585
|
+
var import_react_native41 = require("react-native");
|
|
3517
3586
|
|
|
3518
3587
|
// src/components/preview/PreviewPage.tsx
|
|
3519
|
-
var
|
|
3588
|
+
var import_react_native21 = require("react-native");
|
|
3520
3589
|
var import_bottom_sheet4 = require("@gorhom/bottom-sheet");
|
|
3521
3590
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3522
3591
|
function PreviewPage({ header, children, contentStyle }) {
|
|
3523
3592
|
const theme = useTheme();
|
|
3524
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
3525
|
-
header ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3593
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_native21.View, { style: { flex: 1 }, children: [
|
|
3594
|
+
header ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native21.View, { children: header }) : null,
|
|
3526
3595
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3527
3596
|
import_bottom_sheet4.BottomSheetScrollView,
|
|
3528
3597
|
{
|
|
@@ -3542,15 +3611,15 @@ function PreviewPage({ header, children, contentStyle }) {
|
|
|
3542
3611
|
}
|
|
3543
3612
|
|
|
3544
3613
|
// src/studio/ui/preview-panel/PreviewPanelHeader.tsx
|
|
3545
|
-
var
|
|
3614
|
+
var import_react_native24 = require("react-native");
|
|
3546
3615
|
|
|
3547
3616
|
// src/components/studio-sheet/StudioSheetHeader.tsx
|
|
3548
|
-
var
|
|
3617
|
+
var import_react_native22 = require("react-native");
|
|
3549
3618
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3550
3619
|
function StudioSheetHeader({ left, center, right, style }) {
|
|
3551
3620
|
const theme = useTheme();
|
|
3552
3621
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
3553
|
-
|
|
3622
|
+
import_react_native22.View,
|
|
3554
3623
|
{
|
|
3555
3624
|
style: [
|
|
3556
3625
|
{
|
|
@@ -3563,17 +3632,17 @@ function StudioSheetHeader({ left, center, right, style }) {
|
|
|
3563
3632
|
style
|
|
3564
3633
|
],
|
|
3565
3634
|
children: [
|
|
3566
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3567
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3568
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3635
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.View, { style: { flexDirection: "row", alignItems: "center" }, children: left }),
|
|
3636
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.View, { style: { flex: 1, alignItems: "center" }, children: center }),
|
|
3637
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.View, { style: { flexDirection: "row", alignItems: "center" }, children: right })
|
|
3569
3638
|
]
|
|
3570
3639
|
}
|
|
3571
3640
|
);
|
|
3572
3641
|
}
|
|
3573
3642
|
|
|
3574
3643
|
// src/components/studio-sheet/StudioSheetHeaderIconButton.tsx
|
|
3575
|
-
var
|
|
3576
|
-
var
|
|
3644
|
+
var React22 = __toESM(require("react"));
|
|
3645
|
+
var import_react_native23 = require("react-native");
|
|
3577
3646
|
var import_liquid_glass5 = require("@callstack/liquid-glass");
|
|
3578
3647
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3579
3648
|
function StudioSheetHeaderIconButton({
|
|
@@ -3587,19 +3656,19 @@ function StudioSheetHeaderIconButton({
|
|
|
3587
3656
|
}) {
|
|
3588
3657
|
const theme = useTheme();
|
|
3589
3658
|
const size = 44;
|
|
3590
|
-
const [pressed, setPressed] =
|
|
3659
|
+
const [pressed, setPressed] = React22.useState(false);
|
|
3591
3660
|
const solidBg = intent === "danger" ? theme.colors.danger : intent === "primary" ? theme.colors.primary : theme.colors.neutral;
|
|
3592
3661
|
const glassFallbackBg = theme.scheme === "dark" ? "#18181B" : "#F6F6F6";
|
|
3593
3662
|
const glassInnerBg = intent === "danger" ? theme.colors.danger : theme.colors.primary;
|
|
3594
3663
|
const resolvedOpacity = disabled ? 0.6 : pressed ? 0.9 : 1;
|
|
3595
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3664
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native23.View, { style, children: appearance === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3596
3665
|
import_liquid_glass5.LiquidGlassView,
|
|
3597
3666
|
{
|
|
3598
3667
|
style: [{ borderRadius: 100 }, !import_liquid_glass5.isLiquidGlassSupported && { backgroundColor: glassFallbackBg }],
|
|
3599
3668
|
interactive: true,
|
|
3600
3669
|
effect: "clear",
|
|
3601
3670
|
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3602
|
-
|
|
3671
|
+
import_react_native23.View,
|
|
3603
3672
|
{
|
|
3604
3673
|
style: {
|
|
3605
3674
|
width: size,
|
|
@@ -3611,7 +3680,7 @@ function StudioSheetHeaderIconButton({
|
|
|
3611
3680
|
opacity: resolvedOpacity
|
|
3612
3681
|
},
|
|
3613
3682
|
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3614
|
-
|
|
3683
|
+
import_react_native23.Pressable,
|
|
3615
3684
|
{
|
|
3616
3685
|
accessibilityRole: "button",
|
|
3617
3686
|
accessibilityLabel,
|
|
@@ -3630,7 +3699,7 @@ function StudioSheetHeaderIconButton({
|
|
|
3630
3699
|
)
|
|
3631
3700
|
}
|
|
3632
3701
|
) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3633
|
-
|
|
3702
|
+
import_react_native23.View,
|
|
3634
3703
|
{
|
|
3635
3704
|
style: {
|
|
3636
3705
|
width: size,
|
|
@@ -3642,7 +3711,7 @@ function StudioSheetHeaderIconButton({
|
|
|
3642
3711
|
opacity: resolvedOpacity
|
|
3643
3712
|
},
|
|
3644
3713
|
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3645
|
-
|
|
3714
|
+
import_react_native23.Pressable,
|
|
3646
3715
|
{
|
|
3647
3716
|
accessibilityRole: "button",
|
|
3648
3717
|
accessibilityLabel,
|
|
@@ -3669,7 +3738,7 @@ function PreviewPanelHeader({ isOwner, onClose, onNavigateHome, onGoToChat }) {
|
|
|
3669
3738
|
{
|
|
3670
3739
|
left: onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", appearance: "glass", intent: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IconHome, { size: 20, colorToken: "onPrimary" }) }) : null,
|
|
3671
3740
|
center: null,
|
|
3672
|
-
right: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
3741
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native24.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
3673
3742
|
isOwner ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3674
3743
|
StudioSheetHeaderIconButton,
|
|
3675
3744
|
{
|
|
@@ -3688,10 +3757,10 @@ function PreviewPanelHeader({ isOwner, onClose, onNavigateHome, onGoToChat }) {
|
|
|
3688
3757
|
}
|
|
3689
3758
|
|
|
3690
3759
|
// src/components/preview/PreviewHeroCard.tsx
|
|
3691
|
-
var
|
|
3760
|
+
var import_react_native26 = require("react-native");
|
|
3692
3761
|
|
|
3693
3762
|
// src/components/primitives/Surface.tsx
|
|
3694
|
-
var
|
|
3763
|
+
var import_react_native25 = require("react-native");
|
|
3695
3764
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3696
3765
|
function backgroundFor(variant, theme) {
|
|
3697
3766
|
const { colors } = theme;
|
|
@@ -3710,7 +3779,7 @@ function backgroundFor(variant, theme) {
|
|
|
3710
3779
|
function Surface({ variant = "surface", border = false, style, ...props }) {
|
|
3711
3780
|
const theme = useTheme();
|
|
3712
3781
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3713
|
-
|
|
3782
|
+
import_react_native25.View,
|
|
3714
3783
|
{
|
|
3715
3784
|
...props,
|
|
3716
3785
|
style: [
|
|
@@ -3766,32 +3835,32 @@ function PreviewHeroCard({
|
|
|
3766
3835
|
},
|
|
3767
3836
|
style
|
|
3768
3837
|
],
|
|
3769
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
3770
|
-
background ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3771
|
-
image ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3772
|
-
overlayTopLeft ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3773
|
-
overlayBottom ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3838
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native26.View, { style: { flex: 1 }, children: [
|
|
3839
|
+
background ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native26.View, { style: { position: "absolute", inset: 0 }, children: background }) : null,
|
|
3840
|
+
image ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native26.View, { style: { position: "absolute", inset: 0 }, children: image }) : null,
|
|
3841
|
+
overlayTopLeft ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native26.View, { style: { position: "absolute", top: theme.spacing.sm, left: theme.spacing.sm, zIndex: 2 }, children: overlayTopLeft }) : null,
|
|
3842
|
+
overlayBottom ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native26.View, { style: { flex: 1, justifyContent: "flex-end" }, children: overlayBottom }) : null
|
|
3774
3843
|
] })
|
|
3775
3844
|
}
|
|
3776
3845
|
);
|
|
3777
3846
|
}
|
|
3778
3847
|
|
|
3779
3848
|
// src/components/preview/PreviewPlaceholder.tsx
|
|
3780
|
-
var
|
|
3781
|
-
var
|
|
3849
|
+
var React23 = __toESM(require("react"));
|
|
3850
|
+
var import_react_native27 = require("react-native");
|
|
3782
3851
|
var import_expo_linear_gradient2 = require("expo-linear-gradient");
|
|
3783
3852
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
3784
3853
|
function PreviewPlaceholder({ visible, style }) {
|
|
3785
3854
|
if (!visible) return null;
|
|
3786
|
-
const opacityAnim =
|
|
3787
|
-
|
|
3855
|
+
const opacityAnim = React23.useRef(new import_react_native27.Animated.Value(0)).current;
|
|
3856
|
+
React23.useEffect(() => {
|
|
3788
3857
|
if (!visible) return;
|
|
3789
|
-
const animation =
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3858
|
+
const animation = import_react_native27.Animated.loop(
|
|
3859
|
+
import_react_native27.Animated.sequence([
|
|
3860
|
+
import_react_native27.Animated.timing(opacityAnim, { toValue: 1, duration: 1500, useNativeDriver: true }),
|
|
3861
|
+
import_react_native27.Animated.timing(opacityAnim, { toValue: 2, duration: 1500, useNativeDriver: true }),
|
|
3862
|
+
import_react_native27.Animated.timing(opacityAnim, { toValue: 3, duration: 1500, useNativeDriver: true }),
|
|
3863
|
+
import_react_native27.Animated.timing(opacityAnim, { toValue: 0, duration: 1500, useNativeDriver: true })
|
|
3795
3864
|
])
|
|
3796
3865
|
);
|
|
3797
3866
|
animation.start();
|
|
@@ -3802,7 +3871,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3802
3871
|
const opacity3 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 1, 0] });
|
|
3803
3872
|
const opacity4 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 0, 1] });
|
|
3804
3873
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
3805
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3874
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native27.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3806
3875
|
import_expo_linear_gradient2.LinearGradient,
|
|
3807
3876
|
{
|
|
3808
3877
|
colors: ["rgba(98, 0, 238, 0.45)", "rgba(168, 85, 247, 0.35)"],
|
|
@@ -3811,7 +3880,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3811
3880
|
style: { width: "100%", height: "100%" }
|
|
3812
3881
|
}
|
|
3813
3882
|
) }),
|
|
3814
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3883
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native27.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity2 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3815
3884
|
import_expo_linear_gradient2.LinearGradient,
|
|
3816
3885
|
{
|
|
3817
3886
|
colors: ["rgba(168, 85, 247, 0.45)", "rgba(139, 92, 246, 0.35)"],
|
|
@@ -3820,7 +3889,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3820
3889
|
style: { width: "100%", height: "100%" }
|
|
3821
3890
|
}
|
|
3822
3891
|
) }),
|
|
3823
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3892
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native27.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity3 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3824
3893
|
import_expo_linear_gradient2.LinearGradient,
|
|
3825
3894
|
{
|
|
3826
3895
|
colors: ["rgba(139, 92, 246, 0.45)", "rgba(126, 34, 206, 0.35)"],
|
|
@@ -3829,7 +3898,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3829
3898
|
style: { width: "100%", height: "100%" }
|
|
3830
3899
|
}
|
|
3831
3900
|
) }),
|
|
3832
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3901
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native27.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity4 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3833
3902
|
import_expo_linear_gradient2.LinearGradient,
|
|
3834
3903
|
{
|
|
3835
3904
|
colors: ["rgba(126, 34, 206, 0.45)", "rgba(98, 0, 238, 0.35)"],
|
|
@@ -3842,12 +3911,12 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3842
3911
|
}
|
|
3843
3912
|
|
|
3844
3913
|
// src/components/preview/PreviewImage.tsx
|
|
3845
|
-
var
|
|
3914
|
+
var import_react_native28 = require("react-native");
|
|
3846
3915
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
3847
3916
|
function PreviewImage({ uri, onLoad, style }) {
|
|
3848
3917
|
if (!uri) return null;
|
|
3849
3918
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3850
|
-
|
|
3919
|
+
import_react_native28.Image,
|
|
3851
3920
|
{
|
|
3852
3921
|
source: { uri },
|
|
3853
3922
|
resizeMode: "cover",
|
|
@@ -3858,7 +3927,7 @@ function PreviewImage({ uri, onLoad, style }) {
|
|
|
3858
3927
|
}
|
|
3859
3928
|
|
|
3860
3929
|
// src/components/preview/StatsBar.tsx
|
|
3861
|
-
var
|
|
3930
|
+
var import_react_native29 = require("react-native");
|
|
3862
3931
|
var import_liquid_glass6 = require("@callstack/liquid-glass");
|
|
3863
3932
|
var import_lucide_react_native5 = require("lucide-react-native");
|
|
3864
3933
|
|
|
@@ -3891,7 +3960,7 @@ function StatsBar({
|
|
|
3891
3960
|
const theme = useTheme();
|
|
3892
3961
|
const statsBgColor = theme.scheme === "dark" ? "rgba(24, 24, 27, 0.5)" : "rgba(255, 255, 255, 0.5)";
|
|
3893
3962
|
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3894
|
-
|
|
3963
|
+
import_react_native29.View,
|
|
3895
3964
|
{
|
|
3896
3965
|
style: [
|
|
3897
3966
|
{ position: "absolute", bottom: 12, width: "100%", paddingHorizontal: 12 },
|
|
@@ -3907,15 +3976,15 @@ function StatsBar({
|
|
|
3907
3976
|
!import_liquid_glass6.isLiquidGlassSupported && { backgroundColor: statsBgColor }
|
|
3908
3977
|
],
|
|
3909
3978
|
effect: "clear",
|
|
3910
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
3979
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native29.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16 }, children: [
|
|
3911
3980
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3912
|
-
|
|
3981
|
+
import_react_native29.Pressable,
|
|
3913
3982
|
{
|
|
3914
3983
|
disabled: !onPressLike,
|
|
3915
3984
|
onPress: onPressLike,
|
|
3916
3985
|
hitSlop: 8,
|
|
3917
3986
|
style: { paddingVertical: 8 },
|
|
3918
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
3987
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native29.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
3919
3988
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3920
3989
|
import_lucide_react_native5.Heart,
|
|
3921
3990
|
{
|
|
@@ -3925,7 +3994,7 @@ function StatsBar({
|
|
|
3925
3994
|
fill: isLiked ? theme.colors.danger : "transparent"
|
|
3926
3995
|
}
|
|
3927
3996
|
),
|
|
3928
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3997
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native29.View, { style: { width: 4 } }),
|
|
3929
3998
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3930
3999
|
Text,
|
|
3931
4000
|
{
|
|
@@ -3941,22 +4010,22 @@ function StatsBar({
|
|
|
3941
4010
|
}
|
|
3942
4011
|
),
|
|
3943
4012
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3944
|
-
|
|
4013
|
+
import_react_native29.Pressable,
|
|
3945
4014
|
{
|
|
3946
4015
|
disabled: !onPressComments,
|
|
3947
4016
|
onPress: onPressComments,
|
|
3948
4017
|
hitSlop: 8,
|
|
3949
4018
|
style: { paddingVertical: 8 },
|
|
3950
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
4019
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native29.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
3951
4020
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react_native5.MessageCircle, { size: 16, strokeWidth: 2.5, color: "#FFFFFF" }),
|
|
3952
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
4021
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native29.View, { style: { width: 4 } }),
|
|
3953
4022
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: commentCount })
|
|
3954
4023
|
] })
|
|
3955
4024
|
}
|
|
3956
4025
|
),
|
|
3957
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
3958
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3959
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
4026
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native29.View, { style: { flexDirection: "row", alignItems: "center", paddingVertical: 8 }, children: [
|
|
4027
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native29.View, { style: { transform: [{ scaleY: -1 }] }, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(MergeIcon, { width: 14, height: 14, color: "#FFFFFF" }) }),
|
|
4028
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native29.View, { style: { width: 4 } }),
|
|
3960
4029
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: forkCount })
|
|
3961
4030
|
] })
|
|
3962
4031
|
] })
|
|
@@ -3967,7 +4036,7 @@ function StatsBar({
|
|
|
3967
4036
|
}
|
|
3968
4037
|
|
|
3969
4038
|
// src/components/preview/PreviewStatusBadge.tsx
|
|
3970
|
-
var
|
|
4039
|
+
var import_react_native30 = require("react-native");
|
|
3971
4040
|
var import_lucide_react_native6 = require("lucide-react-native");
|
|
3972
4041
|
|
|
3973
4042
|
// src/data/apps/types.ts
|
|
@@ -4012,7 +4081,7 @@ function PreviewStatusBadge({ status }) {
|
|
|
4012
4081
|
const IconComp = STATUS_ICON[status];
|
|
4013
4082
|
const label = APP_STATUS_LABEL[status] ?? status;
|
|
4014
4083
|
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
4015
|
-
|
|
4084
|
+
import_react_native30.View,
|
|
4016
4085
|
{
|
|
4017
4086
|
style: {
|
|
4018
4087
|
flexDirection: "row",
|
|
@@ -4065,10 +4134,10 @@ function PreviewHeroSection({
|
|
|
4065
4134
|
}
|
|
4066
4135
|
|
|
4067
4136
|
// src/studio/ui/preview-panel/PreviewMetaSection.tsx
|
|
4068
|
-
var
|
|
4137
|
+
var import_react_native32 = require("react-native");
|
|
4069
4138
|
|
|
4070
4139
|
// src/components/preview/PreviewMetaRow.tsx
|
|
4071
|
-
var
|
|
4140
|
+
var import_react_native31 = require("react-native");
|
|
4072
4141
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
4073
4142
|
function PreviewMetaRow({
|
|
4074
4143
|
avatarUri,
|
|
@@ -4080,10 +4149,10 @@ function PreviewMetaRow({
|
|
|
4080
4149
|
style
|
|
4081
4150
|
}) {
|
|
4082
4151
|
const theme = useTheme();
|
|
4083
|
-
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
4084
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
4152
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react_native31.View, { style: [{ alignSelf: "stretch" }, style], children: [
|
|
4153
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react_native31.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4085
4154
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Avatar, { uri: avatarUri, name: creatorName, size: 24, style: { marginRight: theme.spacing.sm } }),
|
|
4086
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
4155
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react_native31.View, { style: { flexDirection: "row", alignItems: "center", flex: 1, minWidth: 0, marginRight: theme.spacing.sm }, children: [
|
|
4087
4156
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4088
4157
|
Text,
|
|
4089
4158
|
{
|
|
@@ -4098,9 +4167,9 @@ function PreviewMetaRow({
|
|
|
4098
4167
|
children: title
|
|
4099
4168
|
}
|
|
4100
4169
|
),
|
|
4101
|
-
tag ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4170
|
+
tag ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_native31.View, { style: { marginLeft: theme.spacing.sm }, children: tag }) : null
|
|
4102
4171
|
] }),
|
|
4103
|
-
rightMetric ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4172
|
+
rightMetric ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_native31.View, { children: rightMetric }) : null
|
|
4104
4173
|
] }),
|
|
4105
4174
|
subtitle ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4106
4175
|
Text,
|
|
@@ -4156,9 +4225,9 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
|
|
|
4156
4225
|
subtitle: app.description,
|
|
4157
4226
|
avatarUri: (creator == null ? void 0 : creator.avatar) ?? null,
|
|
4158
4227
|
creatorName: (creator == null ? void 0 : creator.name) ?? null,
|
|
4159
|
-
tag: isOwner || app.forkedFromAppId ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
4228
|
+
tag: isOwner || app.forkedFromAppId ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_native32.View, { style: { paddingHorizontal: 8, paddingVertical: 2, borderRadius: 999, backgroundColor: "#3700B3" }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Text, { variant: "caption", style: { color: "#fff", fontWeight: theme.typography.fontWeight.semibold }, children: app.forkedFromAppId ? "Remix" : "Owner" }) }) : null,
|
|
4160
4229
|
rightMetric: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
4161
|
-
|
|
4230
|
+
import_react_native32.View,
|
|
4162
4231
|
{
|
|
4163
4232
|
style: {
|
|
4164
4233
|
flexDirection: "row",
|
|
@@ -4192,10 +4261,10 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
|
|
|
4192
4261
|
}
|
|
4193
4262
|
|
|
4194
4263
|
// src/studio/ui/preview-panel/PreviewCustomizeSection.tsx
|
|
4195
|
-
var
|
|
4264
|
+
var import_react_native34 = require("react-native");
|
|
4196
4265
|
|
|
4197
4266
|
// src/studio/ui/preview-panel/PressableCardRow.tsx
|
|
4198
|
-
var
|
|
4267
|
+
var import_react_native33 = require("react-native");
|
|
4199
4268
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
4200
4269
|
function PressableCardRow({
|
|
4201
4270
|
accessibilityLabel,
|
|
@@ -4208,20 +4277,20 @@ function PressableCardRow({
|
|
|
4208
4277
|
style
|
|
4209
4278
|
}) {
|
|
4210
4279
|
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4211
|
-
|
|
4280
|
+
import_react_native33.Pressable,
|
|
4212
4281
|
{
|
|
4213
4282
|
accessibilityRole: "button",
|
|
4214
4283
|
accessibilityLabel,
|
|
4215
4284
|
disabled,
|
|
4216
4285
|
onPress,
|
|
4217
4286
|
style: ({ pressed }) => ({ opacity: disabled ? 0.6 : pressed ? 0.85 : 1 }),
|
|
4218
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Card, { padded: false, border: false, style, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
4287
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Card, { padded: false, border: false, style, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native33.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4219
4288
|
left,
|
|
4220
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
4289
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native33.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4221
4290
|
title,
|
|
4222
4291
|
subtitle ? subtitle : null
|
|
4223
4292
|
] }),
|
|
4224
|
-
right ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4293
|
+
right ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_native33.View, { style: { marginLeft: 16 }, children: right }) : null
|
|
4225
4294
|
] }) })
|
|
4226
4295
|
}
|
|
4227
4296
|
);
|
|
@@ -4263,7 +4332,7 @@ function PreviewCustomizeSection({
|
|
|
4263
4332
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
4264
4333
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SectionTitle, { children: "Customize" }),
|
|
4265
4334
|
showProcessing ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4266
|
-
|
|
4335
|
+
import_react_native34.View,
|
|
4267
4336
|
{
|
|
4268
4337
|
style: {
|
|
4269
4338
|
flexDirection: "row",
|
|
@@ -4277,7 +4346,7 @@ function PreviewCustomizeSection({
|
|
|
4277
4346
|
},
|
|
4278
4347
|
children: [
|
|
4279
4348
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4280
|
-
|
|
4349
|
+
import_react_native34.View,
|
|
4281
4350
|
{
|
|
4282
4351
|
style: {
|
|
4283
4352
|
width: 40,
|
|
@@ -4288,10 +4357,10 @@ function PreviewCustomizeSection({
|
|
|
4288
4357
|
backgroundColor: withAlpha(theme.colors.warning, 0.1),
|
|
4289
4358
|
marginRight: theme.spacing.lg
|
|
4290
4359
|
},
|
|
4291
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4360
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native34.ActivityIndicator, { color: theme.colors.warning, size: "small" })
|
|
4292
4361
|
}
|
|
4293
4362
|
),
|
|
4294
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4363
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native34.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4295
4364
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: app.status === "error" ? "Error" : "Processing" }),
|
|
4296
4365
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: statusDescription(app.status, app.statusError) })
|
|
4297
4366
|
] })
|
|
@@ -4312,7 +4381,7 @@ function PreviewCustomizeSection({
|
|
|
4312
4381
|
marginBottom: theme.spacing.sm
|
|
4313
4382
|
},
|
|
4314
4383
|
left: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4315
|
-
|
|
4384
|
+
import_react_native34.View,
|
|
4316
4385
|
{
|
|
4317
4386
|
style: {
|
|
4318
4387
|
width: 40,
|
|
@@ -4345,7 +4414,7 @@ function PreviewCustomizeSection({
|
|
|
4345
4414
|
marginBottom: theme.spacing.sm
|
|
4346
4415
|
},
|
|
4347
4416
|
left: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4348
|
-
|
|
4417
|
+
import_react_native34.View,
|
|
4349
4418
|
{
|
|
4350
4419
|
style: {
|
|
4351
4420
|
width: 40,
|
|
@@ -4368,17 +4437,17 @@ function PreviewCustomizeSection({
|
|
|
4368
4437
|
}
|
|
4369
4438
|
|
|
4370
4439
|
// src/studio/ui/preview-panel/PreviewCollaborateSection.tsx
|
|
4371
|
-
var
|
|
4372
|
-
var
|
|
4440
|
+
var React29 = __toESM(require("react"));
|
|
4441
|
+
var import_react_native40 = require("react-native");
|
|
4373
4442
|
var import_lucide_react_native9 = require("lucide-react-native");
|
|
4374
4443
|
|
|
4375
4444
|
// src/components/merge-requests/MergeRequestStatusCard.tsx
|
|
4376
|
-
var
|
|
4377
|
-
var
|
|
4445
|
+
var React25 = __toESM(require("react"));
|
|
4446
|
+
var import_react_native36 = require("react-native");
|
|
4378
4447
|
var import_lucide_react_native7 = require("lucide-react-native");
|
|
4379
4448
|
|
|
4380
4449
|
// src/components/primitives/MarkdownText.tsx
|
|
4381
|
-
var
|
|
4450
|
+
var import_react_native35 = require("react-native");
|
|
4382
4451
|
var import_react_native_markdown_display = __toESM(require("react-native-markdown-display"));
|
|
4383
4452
|
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
4384
4453
|
function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
@@ -4391,7 +4460,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
|
4391
4460
|
const codeTextColor = isDark ? "#FFFFFF" : theme.colors.text;
|
|
4392
4461
|
const paragraphBottom = variant === "mergeRequest" ? 8 : 6;
|
|
4393
4462
|
const baseLineHeight = variant === "mergeRequest" ? 22 : 20;
|
|
4394
|
-
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4463
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_react_native35.View, { style, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4395
4464
|
import_react_native_markdown_display.default,
|
|
4396
4465
|
{
|
|
4397
4466
|
style: {
|
|
@@ -4404,7 +4473,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
|
4404
4473
|
paddingHorizontal: variant === "mergeRequest" ? 6 : 4,
|
|
4405
4474
|
paddingVertical: variant === "mergeRequest" ? 2 : 0,
|
|
4406
4475
|
borderRadius: variant === "mergeRequest" ? 6 : 4,
|
|
4407
|
-
fontFamily:
|
|
4476
|
+
fontFamily: import_react_native35.Platform.OS === "ios" ? "Menlo" : "monospace",
|
|
4408
4477
|
fontSize: 13
|
|
4409
4478
|
},
|
|
4410
4479
|
code_block: {
|
|
@@ -4455,11 +4524,11 @@ function toIsoString(input) {
|
|
|
4455
4524
|
}
|
|
4456
4525
|
|
|
4457
4526
|
// src/components/merge-requests/useControlledExpansion.ts
|
|
4458
|
-
var
|
|
4527
|
+
var React24 = __toESM(require("react"));
|
|
4459
4528
|
function useControlledExpansion(props) {
|
|
4460
|
-
const [uncontrolled, setUncontrolled] =
|
|
4529
|
+
const [uncontrolled, setUncontrolled] = React24.useState(false);
|
|
4461
4530
|
const expanded = props.expanded ?? uncontrolled;
|
|
4462
|
-
const setExpanded =
|
|
4531
|
+
const setExpanded = React24.useCallback(
|
|
4463
4532
|
(next) => {
|
|
4464
4533
|
var _a;
|
|
4465
4534
|
(_a = props.onExpandedChange) == null ? void 0 : _a.call(props, next);
|
|
@@ -4484,8 +4553,8 @@ function MergeRequestStatusCard({
|
|
|
4484
4553
|
const isDark = theme.scheme === "dark";
|
|
4485
4554
|
const textColor = isDark ? "#FFFFFF" : "#000000";
|
|
4486
4555
|
const subTextColor = isDark ? "#A1A1AA" : "#71717A";
|
|
4487
|
-
const status =
|
|
4488
|
-
const { StatusIcon, iconColor, bgColor, statusText } =
|
|
4556
|
+
const status = React25.useMemo(() => getMergeRequestStatusDisplay(String(mergeRequest.status)), [mergeRequest.status]);
|
|
4557
|
+
const { StatusIcon, iconColor, bgColor, statusText } = React25.useMemo(() => {
|
|
4489
4558
|
switch (mergeRequest.status) {
|
|
4490
4559
|
case "approved":
|
|
4491
4560
|
case "merged":
|
|
@@ -4516,15 +4585,15 @@ function MergeRequestStatusCard({
|
|
|
4516
4585
|
const createdIso = toIsoString(mergeRequest.createdAt ?? null);
|
|
4517
4586
|
const headerTimeAgo = updatedIso ? formatTimeAgo(updatedIso) : "";
|
|
4518
4587
|
const createdTimeAgo = createdIso ? formatTimeAgo(createdIso) : "";
|
|
4519
|
-
const rotate =
|
|
4520
|
-
|
|
4521
|
-
|
|
4588
|
+
const rotate = React25.useRef(new import_react_native36.Animated.Value(expanded ? 1 : 0)).current;
|
|
4589
|
+
React25.useEffect(() => {
|
|
4590
|
+
import_react_native36.Animated.timing(rotate, {
|
|
4522
4591
|
toValue: expanded ? 1 : 0,
|
|
4523
4592
|
duration: 200,
|
|
4524
4593
|
useNativeDriver: true
|
|
4525
4594
|
}).start();
|
|
4526
4595
|
}, [expanded, rotate]);
|
|
4527
|
-
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4596
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native36.Pressable, { onPress: () => setExpanded(!expanded), style: ({ pressed }) => [{ opacity: pressed ? 0.95 : 1 }], children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
4528
4597
|
Card,
|
|
4529
4598
|
{
|
|
4530
4599
|
padded: false,
|
|
@@ -4537,10 +4606,10 @@ function MergeRequestStatusCard({
|
|
|
4537
4606
|
style
|
|
4538
4607
|
],
|
|
4539
4608
|
children: [
|
|
4540
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
4541
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4542
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
4543
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
4609
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native36.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.lg }, children: [
|
|
4610
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native36.View, { style: { width: 40, height: 40, borderRadius: 999, alignItems: "center", justifyContent: "center", backgroundColor: bgColor }, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(StatusIcon, { size: 20, color: iconColor }) }),
|
|
4611
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native36.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4612
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native36.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
4544
4613
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4545
4614
|
Text,
|
|
4546
4615
|
{
|
|
@@ -4559,8 +4628,8 @@ function MergeRequestStatusCard({
|
|
|
4559
4628
|
] }),
|
|
4560
4629
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, numberOfLines: 1, children: mergeRequest.title ?? "Untitled merge request" })
|
|
4561
4630
|
] }),
|
|
4562
|
-
headerRight ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4563
|
-
|
|
4631
|
+
headerRight ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native36.View, { children: headerRight }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4632
|
+
import_react_native36.Animated.View,
|
|
4564
4633
|
{
|
|
4565
4634
|
style: {
|
|
4566
4635
|
transform: [
|
|
@@ -4573,7 +4642,7 @@ function MergeRequestStatusCard({
|
|
|
4573
4642
|
}
|
|
4574
4643
|
)
|
|
4575
4644
|
] }),
|
|
4576
|
-
expanded ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
4645
|
+
expanded ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native36.View, { style: { marginTop: 16, marginLeft: 56 }, children: [
|
|
4577
4646
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4578
4647
|
Text,
|
|
4579
4648
|
{
|
|
@@ -4608,17 +4677,17 @@ function MergeRequestStatusCard({
|
|
|
4608
4677
|
}
|
|
4609
4678
|
|
|
4610
4679
|
// src/components/merge-requests/ReviewMergeRequestCarousel.tsx
|
|
4611
|
-
var
|
|
4612
|
-
var
|
|
4680
|
+
var React28 = __toESM(require("react"));
|
|
4681
|
+
var import_react_native39 = require("react-native");
|
|
4613
4682
|
|
|
4614
4683
|
// src/components/merge-requests/ReviewMergeRequestCard.tsx
|
|
4615
|
-
var
|
|
4616
|
-
var
|
|
4684
|
+
var React27 = __toESM(require("react"));
|
|
4685
|
+
var import_react_native38 = require("react-native");
|
|
4617
4686
|
var import_lucide_react_native8 = require("lucide-react-native");
|
|
4618
4687
|
|
|
4619
4688
|
// src/components/merge-requests/ReviewMergeRequestActionButton.tsx
|
|
4620
|
-
var
|
|
4621
|
-
var
|
|
4689
|
+
var React26 = __toESM(require("react"));
|
|
4690
|
+
var import_react_native37 = require("react-native");
|
|
4622
4691
|
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
4623
4692
|
function ReviewMergeRequestActionButton({
|
|
4624
4693
|
accessibilityLabel,
|
|
@@ -4628,14 +4697,14 @@ function ReviewMergeRequestActionButton({
|
|
|
4628
4697
|
children,
|
|
4629
4698
|
iconOnly
|
|
4630
4699
|
}) {
|
|
4631
|
-
const [pressed, setPressed] =
|
|
4700
|
+
const [pressed, setPressed] = React26.useState(false);
|
|
4632
4701
|
const height = iconOnly ? 36 : 40;
|
|
4633
4702
|
const width = iconOnly ? 36 : void 0;
|
|
4634
4703
|
const paddingHorizontal = iconOnly ? 0 : 16;
|
|
4635
4704
|
const paddingVertical = iconOnly ? 0 : 8;
|
|
4636
4705
|
const opacity = disabled ? 0.5 : pressed ? 0.9 : 1;
|
|
4637
4706
|
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
4638
|
-
|
|
4707
|
+
import_react_native37.View,
|
|
4639
4708
|
{
|
|
4640
4709
|
style: {
|
|
4641
4710
|
width,
|
|
@@ -4650,7 +4719,7 @@ function ReviewMergeRequestActionButton({
|
|
|
4650
4719
|
justifyContent: "center"
|
|
4651
4720
|
},
|
|
4652
4721
|
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
4653
|
-
|
|
4722
|
+
import_react_native37.Pressable,
|
|
4654
4723
|
{
|
|
4655
4724
|
accessibilityRole: "button",
|
|
4656
4725
|
accessibilityLabel,
|
|
@@ -4690,14 +4759,14 @@ function ReviewMergeRequestCard({
|
|
|
4690
4759
|
onTest
|
|
4691
4760
|
}) {
|
|
4692
4761
|
const theme = useTheme();
|
|
4693
|
-
const status =
|
|
4762
|
+
const status = React27.useMemo(() => getMergeRequestStatusDisplay(mr.status), [mr.status]);
|
|
4694
4763
|
const canAct = mr.status === "open";
|
|
4695
|
-
const rotate =
|
|
4696
|
-
|
|
4697
|
-
|
|
4764
|
+
const rotate = React27.useRef(new import_react_native38.Animated.Value(isExpanded ? 1 : 0)).current;
|
|
4765
|
+
React27.useEffect(() => {
|
|
4766
|
+
import_react_native38.Animated.timing(rotate, { toValue: isExpanded ? 1 : 0, duration: 200, useNativeDriver: true }).start();
|
|
4698
4767
|
}, [isExpanded, rotate]);
|
|
4699
4768
|
const position = total > 1 ? `${index + 1}/${total}` : "Merge request";
|
|
4700
|
-
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4769
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native38.Pressable, { onPress: onToggle, style: ({ pressed }) => ({ opacity: pressed ? 0.95 : 1 }), children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4701
4770
|
Card,
|
|
4702
4771
|
{
|
|
4703
4772
|
padded: false,
|
|
@@ -4710,9 +4779,9 @@ function ReviewMergeRequestCard({
|
|
|
4710
4779
|
}
|
|
4711
4780
|
],
|
|
4712
4781
|
children: [
|
|
4713
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4782
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [
|
|
4714
4783
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Avatar, { size: 40, uri: (creator == null ? void 0 : creator.avatar) ?? null, name: (creator == null ? void 0 : creator.name) ?? void 0 }),
|
|
4715
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4784
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4716
4785
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4717
4786
|
Text,
|
|
4718
4787
|
{
|
|
@@ -4728,7 +4797,7 @@ function ReviewMergeRequestCard({
|
|
|
4728
4797
|
] })
|
|
4729
4798
|
] }),
|
|
4730
4799
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4731
|
-
|
|
4800
|
+
import_react_native38.Animated.View,
|
|
4732
4801
|
{
|
|
4733
4802
|
style: {
|
|
4734
4803
|
transform: [{ rotate: rotate.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "180deg"] }) }]
|
|
@@ -4737,7 +4806,7 @@ function ReviewMergeRequestCard({
|
|
|
4737
4806
|
}
|
|
4738
4807
|
)
|
|
4739
4808
|
] }),
|
|
4740
|
-
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4809
|
+
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { marginTop: 16 }, children: [
|
|
4741
4810
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4742
4811
|
Text,
|
|
4743
4812
|
{
|
|
@@ -4755,9 +4824,9 @@ function ReviewMergeRequestCard({
|
|
|
4755
4824
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginBottom: 12 }, children: creator ? `${creator.approvedOpenedMergeRequests} approved merge${creator.approvedOpenedMergeRequests !== 1 ? "s" : ""}` : "Loading stats..." }),
|
|
4756
4825
|
mr.description ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(MarkdownText, { markdown: mr.description, variant: "mergeRequest" }) : null
|
|
4757
4826
|
] }) : null,
|
|
4758
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4759
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4760
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4827
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native38.View, { style: { height: 1, backgroundColor: withAlpha(theme.colors.borderStrong, 0.5), marginTop: 12, marginBottom: 12 } }),
|
|
4828
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
4829
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", gap: 8 }, children: [
|
|
4761
4830
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4762
4831
|
ReviewMergeRequestActionButton,
|
|
4763
4832
|
{
|
|
@@ -4766,7 +4835,7 @@ function ReviewMergeRequestCard({
|
|
|
4766
4835
|
disabled: !canAct || isAnyProcessing,
|
|
4767
4836
|
onPress: onReject,
|
|
4768
4837
|
iconOnly: !isExpanded,
|
|
4769
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4838
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4770
4839
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native8.X, { size: 18, color: "#FFFFFF" }),
|
|
4771
4840
|
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Reject" }) : null
|
|
4772
4841
|
] })
|
|
@@ -4780,10 +4849,10 @@ function ReviewMergeRequestCard({
|
|
|
4780
4849
|
disabled: !canAct || isAnyProcessing,
|
|
4781
4850
|
onPress: onApprove,
|
|
4782
4851
|
iconOnly: !isExpanded,
|
|
4783
|
-
children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4784
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4852
|
+
children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4853
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native38.ActivityIndicator, { size: "small", color: "#FFFFFF" }),
|
|
4785
4854
|
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Processing" }) : null
|
|
4786
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4855
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4787
4856
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native8.Check, { size: 18, color: "#FFFFFF" }),
|
|
4788
4857
|
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Approve" }) : null
|
|
4789
4858
|
] })
|
|
@@ -4798,7 +4867,7 @@ function ReviewMergeRequestCard({
|
|
|
4798
4867
|
disabled: isBuilding || isTestingThis,
|
|
4799
4868
|
onPress: onTest,
|
|
4800
4869
|
iconOnly: !isExpanded,
|
|
4801
|
-
children: isTestingThis ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4870
|
+
children: isTestingThis ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native38.ActivityIndicator, { size: "small", color: "#888" }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4802
4871
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native8.Play, { size: 14, color: theme.colors.text }),
|
|
4803
4872
|
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: theme.colors.text, fontWeight: theme.typography.fontWeight.semibold }, children: "Test" }) : null
|
|
4804
4873
|
] })
|
|
@@ -4824,32 +4893,32 @@ function ReviewMergeRequestCarousel({
|
|
|
4824
4893
|
style
|
|
4825
4894
|
}) {
|
|
4826
4895
|
const theme = useTheme();
|
|
4827
|
-
const { width } = (0,
|
|
4828
|
-
const [expanded, setExpanded] =
|
|
4829
|
-
const carouselScrollX =
|
|
4896
|
+
const { width } = (0, import_react_native39.useWindowDimensions)();
|
|
4897
|
+
const [expanded, setExpanded] = React28.useState({});
|
|
4898
|
+
const carouselScrollX = React28.useRef(new import_react_native39.Animated.Value(0)).current;
|
|
4830
4899
|
const peekAmount = 24;
|
|
4831
4900
|
const gap = 16;
|
|
4832
|
-
const cardWidth =
|
|
4901
|
+
const cardWidth = React28.useMemo(() => Math.max(1, width - theme.spacing.lg * 2 - peekAmount), [peekAmount, theme.spacing.lg, width]);
|
|
4833
4902
|
const snapInterval = cardWidth + gap;
|
|
4834
4903
|
const dotColor = theme.scheme === "dark" ? "#FFFFFF" : "#000000";
|
|
4835
4904
|
if (mergeRequests.length === 0) return null;
|
|
4836
|
-
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
4905
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native39.View, { style: [{ marginHorizontal: -theme.spacing.lg }, style], children: [
|
|
4837
4906
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4838
|
-
|
|
4907
|
+
import_react_native39.FlatList,
|
|
4839
4908
|
{
|
|
4840
4909
|
horizontal: true,
|
|
4841
4910
|
data: mergeRequests,
|
|
4842
4911
|
keyExtractor: (mr) => mr.id,
|
|
4843
4912
|
showsHorizontalScrollIndicator: false,
|
|
4844
4913
|
contentContainerStyle: { paddingHorizontal: theme.spacing.lg, paddingVertical: theme.spacing.sm },
|
|
4845
|
-
ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4914
|
+
ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native39.View, { style: { width: gap } }),
|
|
4846
4915
|
snapToAlignment: "start",
|
|
4847
4916
|
decelerationRate: "fast",
|
|
4848
4917
|
snapToInterval: snapInterval,
|
|
4849
4918
|
disableIntervalMomentum: true,
|
|
4850
4919
|
style: { paddingRight: peekAmount },
|
|
4851
|
-
ListFooterComponent: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4852
|
-
onScroll:
|
|
4920
|
+
ListFooterComponent: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native39.View, { style: { width: peekAmount } }),
|
|
4921
|
+
onScroll: import_react_native39.Animated.event([{ nativeEvent: { contentOffset: { x: carouselScrollX } } }], {
|
|
4853
4922
|
useNativeDriver: false
|
|
4854
4923
|
}),
|
|
4855
4924
|
scrollEventThrottle: 16,
|
|
@@ -4860,7 +4929,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4860
4929
|
const isProcessing = Boolean(processingMrId && processingMrId === item.id);
|
|
4861
4930
|
const isAnyProcessing = Boolean(processingMrId);
|
|
4862
4931
|
const isTestingThis = Boolean(testingMrId && testingMrId === item.id);
|
|
4863
|
-
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4932
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native39.View, { style: { width: cardWidth }, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4864
4933
|
ReviewMergeRequestCard,
|
|
4865
4934
|
{
|
|
4866
4935
|
mr: item,
|
|
@@ -4881,7 +4950,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4881
4950
|
}
|
|
4882
4951
|
}
|
|
4883
4952
|
),
|
|
4884
|
-
mergeRequests.length >= 1 ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4953
|
+
mergeRequests.length >= 1 ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native39.View, { style: { flexDirection: "row", justifyContent: "center", columnGap: 8, marginTop: theme.spacing.md }, children: mergeRequests.map((mr, index) => {
|
|
4885
4954
|
const inputRange = [(index - 1) * snapInterval, index * snapInterval, (index + 1) * snapInterval];
|
|
4886
4955
|
const scale = carouselScrollX.interpolate({
|
|
4887
4956
|
inputRange,
|
|
@@ -4894,7 +4963,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4894
4963
|
extrapolate: "clamp"
|
|
4895
4964
|
});
|
|
4896
4965
|
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4897
|
-
|
|
4966
|
+
import_react_native39.Animated.View,
|
|
4898
4967
|
{
|
|
4899
4968
|
style: {
|
|
4900
4969
|
width: 8,
|
|
@@ -4928,7 +4997,7 @@ function PreviewCollaborateSection({
|
|
|
4928
4997
|
onTestMr
|
|
4929
4998
|
}) {
|
|
4930
4999
|
const theme = useTheme();
|
|
4931
|
-
const [submittingMr, setSubmittingMr] =
|
|
5000
|
+
const [submittingMr, setSubmittingMr] = React29.useState(false);
|
|
4932
5001
|
const hasSection = canSubmitMergeRequest || incomingMergeRequests.length > 0 || outgoingMergeRequests.length > 0;
|
|
4933
5002
|
if (!hasSection) return null;
|
|
4934
5003
|
const showActionsSubtitle = canSubmitMergeRequest && onSubmitMergeRequest || onTestMr && incomingMergeRequests.length > 0;
|
|
@@ -4955,7 +5024,7 @@ function PreviewCollaborateSection({
|
|
|
4955
5024
|
accessibilityLabel: "Submit merge request",
|
|
4956
5025
|
disabled: submittingMr,
|
|
4957
5026
|
onPress: () => {
|
|
4958
|
-
|
|
5027
|
+
import_react_native40.Alert.alert(
|
|
4959
5028
|
"Submit Merge Request",
|
|
4960
5029
|
"Are you sure you want to submit your changes to the original app?",
|
|
4961
5030
|
[
|
|
@@ -4981,7 +5050,7 @@ function PreviewCollaborateSection({
|
|
|
4981
5050
|
marginBottom: theme.spacing.sm
|
|
4982
5051
|
},
|
|
4983
5052
|
left: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4984
|
-
|
|
5053
|
+
import_react_native40.View,
|
|
4985
5054
|
{
|
|
4986
5055
|
style: {
|
|
4987
5056
|
width: 40,
|
|
@@ -4992,7 +5061,7 @@ function PreviewCollaborateSection({
|
|
|
4992
5061
|
backgroundColor: withAlpha("#03DAC6", 0.1),
|
|
4993
5062
|
marginRight: theme.spacing.lg
|
|
4994
5063
|
},
|
|
4995
|
-
children: submittingMr ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5064
|
+
children: submittingMr ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native40.ActivityIndicator, { color: "#03DAC6", size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MergeIcon, { width: 20, height: 20, color: "#03DAC6" })
|
|
4996
5065
|
}
|
|
4997
5066
|
),
|
|
4998
5067
|
title: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Submit your new changes" }),
|
|
@@ -5030,13 +5099,13 @@ function PreviewCollaborateSection({
|
|
|
5030
5099
|
children: "History"
|
|
5031
5100
|
}
|
|
5032
5101
|
),
|
|
5033
|
-
outgoingMergeRequests.map((mr) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5102
|
+
outgoingMergeRequests.map((mr) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native40.View, { style: { marginBottom: theme.spacing.sm }, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MergeRequestStatusCard, { mergeRequest: toMergeRequestSummary(mr) }) }, mr.id))
|
|
5034
5103
|
] }) : null
|
|
5035
5104
|
] });
|
|
5036
5105
|
}
|
|
5037
5106
|
|
|
5038
5107
|
// src/studio/ui/preview-panel/usePreviewPanelData.ts
|
|
5039
|
-
var
|
|
5108
|
+
var React31 = __toESM(require("react"));
|
|
5040
5109
|
|
|
5041
5110
|
// src/data/apps/images/remote.ts
|
|
5042
5111
|
var AppImagesRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -5087,7 +5156,7 @@ var AppImagesRepositoryImpl = class extends BaseRepository {
|
|
|
5087
5156
|
var appImagesRepository = new AppImagesRepositoryImpl(appImagesRemoteDataSource);
|
|
5088
5157
|
|
|
5089
5158
|
// src/studio/hooks/useAppStats.ts
|
|
5090
|
-
var
|
|
5159
|
+
var React30 = __toESM(require("react"));
|
|
5091
5160
|
var Haptics2 = __toESM(require("expo-haptics"));
|
|
5092
5161
|
|
|
5093
5162
|
// src/data/likes/remote.ts
|
|
@@ -5156,34 +5225,34 @@ function useAppStats({
|
|
|
5156
5225
|
initialIsLiked = false,
|
|
5157
5226
|
onOpenComments
|
|
5158
5227
|
}) {
|
|
5159
|
-
const [likeCount, setLikeCount] =
|
|
5160
|
-
const [commentCount, setCommentCount] =
|
|
5161
|
-
const [forkCount, setForkCount] =
|
|
5162
|
-
const [isLiked, setIsLiked] =
|
|
5163
|
-
const didMutateRef =
|
|
5164
|
-
const lastAppIdRef =
|
|
5165
|
-
|
|
5228
|
+
const [likeCount, setLikeCount] = React30.useState(initialLikes);
|
|
5229
|
+
const [commentCount, setCommentCount] = React30.useState(initialComments);
|
|
5230
|
+
const [forkCount, setForkCount] = React30.useState(initialForks);
|
|
5231
|
+
const [isLiked, setIsLiked] = React30.useState(initialIsLiked);
|
|
5232
|
+
const didMutateRef = React30.useRef(false);
|
|
5233
|
+
const lastAppIdRef = React30.useRef("");
|
|
5234
|
+
React30.useEffect(() => {
|
|
5166
5235
|
if (lastAppIdRef.current === appId) return;
|
|
5167
5236
|
lastAppIdRef.current = appId;
|
|
5168
5237
|
didMutateRef.current = false;
|
|
5169
5238
|
}, [appId]);
|
|
5170
|
-
|
|
5239
|
+
React30.useEffect(() => {
|
|
5171
5240
|
if (didMutateRef.current) return;
|
|
5172
5241
|
setLikeCount(initialLikes);
|
|
5173
5242
|
}, [appId, initialLikes]);
|
|
5174
|
-
|
|
5243
|
+
React30.useEffect(() => {
|
|
5175
5244
|
if (didMutateRef.current) return;
|
|
5176
5245
|
setCommentCount(initialComments);
|
|
5177
5246
|
}, [appId, initialComments]);
|
|
5178
|
-
|
|
5247
|
+
React30.useEffect(() => {
|
|
5179
5248
|
if (didMutateRef.current) return;
|
|
5180
5249
|
setForkCount(initialForks);
|
|
5181
5250
|
}, [appId, initialForks]);
|
|
5182
|
-
|
|
5251
|
+
React30.useEffect(() => {
|
|
5183
5252
|
if (didMutateRef.current) return;
|
|
5184
5253
|
setIsLiked(initialIsLiked);
|
|
5185
5254
|
}, [appId, initialIsLiked]);
|
|
5186
|
-
const handleLike =
|
|
5255
|
+
const handleLike = React30.useCallback(async () => {
|
|
5187
5256
|
var _a, _b;
|
|
5188
5257
|
if (!appId) return;
|
|
5189
5258
|
didMutateRef.current = true;
|
|
@@ -5207,7 +5276,7 @@ function useAppStats({
|
|
|
5207
5276
|
setLikeCount((prev) => Math.max(0, prev + (newIsLiked ? -1 : 1)));
|
|
5208
5277
|
}
|
|
5209
5278
|
}, [appId, isLiked, likeCount]);
|
|
5210
|
-
const handleOpenComments =
|
|
5279
|
+
const handleOpenComments = React30.useCallback(() => {
|
|
5211
5280
|
if (!appId) return;
|
|
5212
5281
|
try {
|
|
5213
5282
|
void Haptics2.impactAsync(Haptics2.ImpactFeedbackStyle.Light);
|
|
@@ -5222,11 +5291,11 @@ function useAppStats({
|
|
|
5222
5291
|
var LIKE_DEBUG_PREFIX = "[COMERGE_LIKE_DEBUG]";
|
|
5223
5292
|
function usePreviewPanelData(params) {
|
|
5224
5293
|
const { app, isOwner, outgoingMergeRequests, onOpenComments, commentCountOverride } = params;
|
|
5225
|
-
const [imageUrl, setImageUrl] =
|
|
5226
|
-
const [imageLoaded, setImageLoaded] =
|
|
5227
|
-
const [insights, setInsights] =
|
|
5228
|
-
const [creator, setCreator] =
|
|
5229
|
-
|
|
5294
|
+
const [imageUrl, setImageUrl] = React31.useState(null);
|
|
5295
|
+
const [imageLoaded, setImageLoaded] = React31.useState(false);
|
|
5296
|
+
const [insights, setInsights] = React31.useState({ likes: 0, comments: 0, forks: 0, downloads: 0 });
|
|
5297
|
+
const [creator, setCreator] = React31.useState(null);
|
|
5298
|
+
React31.useEffect(() => {
|
|
5230
5299
|
if (!(app == null ? void 0 : app.id)) return;
|
|
5231
5300
|
let cancelled = false;
|
|
5232
5301
|
(async () => {
|
|
@@ -5241,7 +5310,7 @@ function usePreviewPanelData(params) {
|
|
|
5241
5310
|
cancelled = true;
|
|
5242
5311
|
};
|
|
5243
5312
|
}, [app == null ? void 0 : app.id]);
|
|
5244
|
-
|
|
5313
|
+
React31.useEffect(() => {
|
|
5245
5314
|
if (!(app == null ? void 0 : app.createdBy)) return;
|
|
5246
5315
|
let cancelled = false;
|
|
5247
5316
|
(async () => {
|
|
@@ -5257,10 +5326,10 @@ function usePreviewPanelData(params) {
|
|
|
5257
5326
|
cancelled = true;
|
|
5258
5327
|
};
|
|
5259
5328
|
}, [app == null ? void 0 : app.createdBy]);
|
|
5260
|
-
|
|
5329
|
+
React31.useEffect(() => {
|
|
5261
5330
|
setImageLoaded(false);
|
|
5262
5331
|
}, [app == null ? void 0 : app.id]);
|
|
5263
|
-
|
|
5332
|
+
React31.useEffect(() => {
|
|
5264
5333
|
if (!(app == null ? void 0 : app.id)) return;
|
|
5265
5334
|
let cancelled = false;
|
|
5266
5335
|
(async () => {
|
|
@@ -5285,7 +5354,7 @@ function usePreviewPanelData(params) {
|
|
|
5285
5354
|
cancelled = true;
|
|
5286
5355
|
};
|
|
5287
5356
|
}, [app == null ? void 0 : app.id]);
|
|
5288
|
-
|
|
5357
|
+
React31.useEffect(() => {
|
|
5289
5358
|
if (!(app == null ? void 0 : app.id)) return;
|
|
5290
5359
|
log.debug(
|
|
5291
5360
|
`${LIKE_DEBUG_PREFIX} usePreviewPanelData.appChanged appId=${app.id} app.isLiked=${String(app.isLiked)}`
|
|
@@ -5299,7 +5368,7 @@ function usePreviewPanelData(params) {
|
|
|
5299
5368
|
initialIsLiked: Boolean(app == null ? void 0 : app.isLiked),
|
|
5300
5369
|
onOpenComments
|
|
5301
5370
|
});
|
|
5302
|
-
const canSubmitMergeRequest =
|
|
5371
|
+
const canSubmitMergeRequest = React31.useMemo(() => {
|
|
5303
5372
|
if (!isOwner) return false;
|
|
5304
5373
|
if (!app) return false;
|
|
5305
5374
|
if (!app.forkedFromAppId) return false;
|
|
@@ -5354,9 +5423,9 @@ function PreviewPanel({
|
|
|
5354
5423
|
});
|
|
5355
5424
|
const header = /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PreviewPanelHeader, { isOwner, onClose, onNavigateHome, onGoToChat });
|
|
5356
5425
|
if (loading || !app) {
|
|
5357
|
-
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PreviewPage, { header, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
5358
|
-
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
5359
|
-
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
5426
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PreviewPage, { header, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native41.View, { style: { flex: 1, justifyContent: "center", alignItems: "center", padding: 24 }, children: [
|
|
5427
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native41.ActivityIndicator, {}),
|
|
5428
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native41.View, { style: { height: 12 } }),
|
|
5360
5429
|
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Text, { variant: "bodyMuted", children: "Loading app\u2026" })
|
|
5361
5430
|
] }) });
|
|
5362
5431
|
}
|
|
@@ -5412,22 +5481,21 @@ function PreviewPanel({
|
|
|
5412
5481
|
}
|
|
5413
5482
|
|
|
5414
5483
|
// src/studio/ui/ChatPanel.tsx
|
|
5415
|
-
var
|
|
5416
|
-
var
|
|
5484
|
+
var React36 = __toESM(require("react"));
|
|
5485
|
+
var import_react_native49 = require("react-native");
|
|
5417
5486
|
|
|
5418
5487
|
// src/components/chat/ChatPage.tsx
|
|
5419
|
-
var
|
|
5420
|
-
var
|
|
5488
|
+
var React34 = __toESM(require("react"));
|
|
5489
|
+
var import_react_native45 = require("react-native");
|
|
5421
5490
|
var import_react_native_safe_area_context4 = require("react-native-safe-area-context");
|
|
5422
|
-
var import_react_native_reanimated2 = __toESM(require("react-native-reanimated"));
|
|
5423
5491
|
|
|
5424
5492
|
// src/components/chat/ChatMessageList.tsx
|
|
5425
|
-
var
|
|
5426
|
-
var
|
|
5493
|
+
var React33 = __toESM(require("react"));
|
|
5494
|
+
var import_react_native44 = require("react-native");
|
|
5427
5495
|
var import_bottom_sheet5 = require("@gorhom/bottom-sheet");
|
|
5428
5496
|
|
|
5429
5497
|
// src/components/chat/ChatMessageBubble.tsx
|
|
5430
|
-
var
|
|
5498
|
+
var import_react_native42 = require("react-native");
|
|
5431
5499
|
var import_lucide_react_native10 = require("lucide-react-native");
|
|
5432
5500
|
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
5433
5501
|
function ChatMessageBubble({ message, renderContent, style }) {
|
|
@@ -5443,7 +5511,7 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5443
5511
|
const bubbleVariant = isHuman ? "surface" : "surfaceRaised";
|
|
5444
5512
|
const cornerStyle = isHuman ? { borderTopRightRadius: 0 } : { borderTopLeftRadius: 0 };
|
|
5445
5513
|
const bodyColor = metaStatus === "success" ? theme.colors.success : metaStatus === "error" ? theme.colors.danger : void 0;
|
|
5446
|
-
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5514
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native42.View, { style: [align, style], children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5447
5515
|
Surface,
|
|
5448
5516
|
{
|
|
5449
5517
|
variant: bubbleVariant,
|
|
@@ -5458,34 +5526,34 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5458
5526
|
},
|
|
5459
5527
|
cornerStyle
|
|
5460
5528
|
],
|
|
5461
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
5529
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native42.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5462
5530
|
isMergeCompleted ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react_native10.CheckCheck, { size: 16, color: theme.colors.success, style: { marginRight: theme.spacing.sm } }) : null,
|
|
5463
5531
|
isMergeApproved ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react_native10.GitMerge, { size: 16, color: theme.colors.text, style: { marginRight: theme.spacing.sm } }) : null,
|
|
5464
|
-
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5532
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native42.View, { style: { flexShrink: 1, minWidth: 0 }, children: renderContent ? renderContent(message) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(MarkdownText, { markdown: message.content, variant: "chat", bodyColor }) })
|
|
5465
5533
|
] })
|
|
5466
5534
|
}
|
|
5467
5535
|
) });
|
|
5468
5536
|
}
|
|
5469
5537
|
|
|
5470
5538
|
// src/components/chat/TypingIndicator.tsx
|
|
5471
|
-
var
|
|
5472
|
-
var
|
|
5539
|
+
var React32 = __toESM(require("react"));
|
|
5540
|
+
var import_react_native43 = require("react-native");
|
|
5473
5541
|
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
5474
5542
|
function TypingIndicator({ style }) {
|
|
5475
5543
|
const theme = useTheme();
|
|
5476
5544
|
const dotColor = theme.colors.textSubtle;
|
|
5477
|
-
const anims =
|
|
5478
|
-
() => [new
|
|
5545
|
+
const anims = React32.useMemo(
|
|
5546
|
+
() => [new import_react_native43.Animated.Value(0.3), new import_react_native43.Animated.Value(0.3), new import_react_native43.Animated.Value(0.3)],
|
|
5479
5547
|
[]
|
|
5480
5548
|
);
|
|
5481
|
-
|
|
5549
|
+
React32.useEffect(() => {
|
|
5482
5550
|
const loops = [];
|
|
5483
5551
|
anims.forEach((a, idx) => {
|
|
5484
|
-
const seq =
|
|
5485
|
-
|
|
5486
|
-
|
|
5552
|
+
const seq = import_react_native43.Animated.sequence([
|
|
5553
|
+
import_react_native43.Animated.timing(a, { toValue: 1, duration: 420, useNativeDriver: true, delay: idx * 140 }),
|
|
5554
|
+
import_react_native43.Animated.timing(a, { toValue: 0.3, duration: 420, useNativeDriver: true })
|
|
5487
5555
|
]);
|
|
5488
|
-
const loop =
|
|
5556
|
+
const loop = import_react_native43.Animated.loop(seq);
|
|
5489
5557
|
loops.push(loop);
|
|
5490
5558
|
loop.start();
|
|
5491
5559
|
});
|
|
@@ -5493,8 +5561,8 @@ function TypingIndicator({ style }) {
|
|
|
5493
5561
|
loops.forEach((l) => l.stop());
|
|
5494
5562
|
};
|
|
5495
5563
|
}, [anims]);
|
|
5496
|
-
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5497
|
-
|
|
5564
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native43.View, { style: [{ flexDirection: "row", alignItems: "center" }, style], children: anims.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5565
|
+
import_react_native43.Animated.View,
|
|
5498
5566
|
{
|
|
5499
5567
|
style: {
|
|
5500
5568
|
width: 8,
|
|
@@ -5503,7 +5571,7 @@ function TypingIndicator({ style }) {
|
|
|
5503
5571
|
marginHorizontal: 3,
|
|
5504
5572
|
backgroundColor: dotColor,
|
|
5505
5573
|
opacity: a,
|
|
5506
|
-
transform: [{ translateY:
|
|
5574
|
+
transform: [{ translateY: import_react_native43.Animated.multiply(import_react_native43.Animated.subtract(a, 0.3), 2) }]
|
|
5507
5575
|
}
|
|
5508
5576
|
},
|
|
5509
5577
|
i
|
|
@@ -5512,39 +5580,43 @@ function TypingIndicator({ style }) {
|
|
|
5512
5580
|
|
|
5513
5581
|
// src/components/chat/ChatMessageList.tsx
|
|
5514
5582
|
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
5515
|
-
var ChatMessageList =
|
|
5583
|
+
var ChatMessageList = React33.forwardRef(
|
|
5516
5584
|
({
|
|
5517
5585
|
messages,
|
|
5518
5586
|
showTypingIndicator = false,
|
|
5519
5587
|
renderMessageContent,
|
|
5520
5588
|
contentStyle,
|
|
5589
|
+
bottomInset = 0,
|
|
5521
5590
|
onNearBottomChange,
|
|
5522
5591
|
nearBottomThreshold = 200
|
|
5523
5592
|
}, ref) => {
|
|
5524
5593
|
const theme = useTheme();
|
|
5525
|
-
const listRef =
|
|
5526
|
-
const nearBottomRef =
|
|
5527
|
-
const initialScrollDoneRef =
|
|
5528
|
-
const lastMessageIdRef =
|
|
5529
|
-
const scrollToBottom =
|
|
5594
|
+
const listRef = React33.useRef(null);
|
|
5595
|
+
const nearBottomRef = React33.useRef(true);
|
|
5596
|
+
const initialScrollDoneRef = React33.useRef(false);
|
|
5597
|
+
const lastMessageIdRef = React33.useRef(null);
|
|
5598
|
+
const scrollToBottom = React33.useCallback((options) => {
|
|
5530
5599
|
var _a;
|
|
5531
5600
|
const animated = (options == null ? void 0 : options.animated) ?? true;
|
|
5532
5601
|
(_a = listRef.current) == null ? void 0 : _a.scrollToEnd({ animated });
|
|
5533
5602
|
}, []);
|
|
5534
|
-
|
|
5535
|
-
const handleScroll =
|
|
5603
|
+
React33.useImperativeHandle(ref, () => ({ scrollToBottom }), [scrollToBottom]);
|
|
5604
|
+
const handleScroll = React33.useCallback(
|
|
5536
5605
|
(e) => {
|
|
5537
5606
|
const { contentOffset, contentSize, layoutMeasurement } = e.nativeEvent;
|
|
5538
|
-
const distanceFromBottom = Math.max(
|
|
5607
|
+
const distanceFromBottom = Math.max(
|
|
5608
|
+
contentSize.height - Math.max(bottomInset, 0) - (contentOffset.y + layoutMeasurement.height),
|
|
5609
|
+
0
|
|
5610
|
+
);
|
|
5539
5611
|
const isNear = distanceFromBottom <= nearBottomThreshold;
|
|
5540
5612
|
if (nearBottomRef.current !== isNear) {
|
|
5541
5613
|
nearBottomRef.current = isNear;
|
|
5542
5614
|
onNearBottomChange == null ? void 0 : onNearBottomChange(isNear);
|
|
5543
5615
|
}
|
|
5544
5616
|
},
|
|
5545
|
-
[nearBottomThreshold, onNearBottomChange]
|
|
5617
|
+
[bottomInset, nearBottomThreshold, onNearBottomChange]
|
|
5546
5618
|
);
|
|
5547
|
-
|
|
5619
|
+
React33.useEffect(() => {
|
|
5548
5620
|
var _a;
|
|
5549
5621
|
if (initialScrollDoneRef.current) return;
|
|
5550
5622
|
if (messages.length === 0) return;
|
|
@@ -5553,7 +5625,7 @@ var ChatMessageList = React32.forwardRef(
|
|
|
5553
5625
|
const id = requestAnimationFrame(() => scrollToBottom({ animated: false }));
|
|
5554
5626
|
return () => cancelAnimationFrame(id);
|
|
5555
5627
|
}, [messages, scrollToBottom]);
|
|
5556
|
-
|
|
5628
|
+
React33.useEffect(() => {
|
|
5557
5629
|
if (!initialScrollDoneRef.current) return;
|
|
5558
5630
|
const lastId = messages.length > 0 ? messages[messages.length - 1].id : null;
|
|
5559
5631
|
const prevLastId = lastMessageIdRef.current;
|
|
@@ -5563,19 +5635,27 @@ var ChatMessageList = React32.forwardRef(
|
|
|
5563
5635
|
const id = requestAnimationFrame(() => scrollToBottom({ animated: true }));
|
|
5564
5636
|
return () => cancelAnimationFrame(id);
|
|
5565
5637
|
}, [messages, scrollToBottom]);
|
|
5566
|
-
|
|
5638
|
+
React33.useEffect(() => {
|
|
5567
5639
|
if (showTypingIndicator && nearBottomRef.current) {
|
|
5568
5640
|
const id = requestAnimationFrame(() => scrollToBottom({ animated: true }));
|
|
5569
5641
|
return () => cancelAnimationFrame(id);
|
|
5570
5642
|
}
|
|
5571
5643
|
return void 0;
|
|
5572
5644
|
}, [showTypingIndicator, scrollToBottom]);
|
|
5645
|
+
React33.useEffect(() => {
|
|
5646
|
+
if (!initialScrollDoneRef.current) return;
|
|
5647
|
+
if (!nearBottomRef.current) return;
|
|
5648
|
+
const id = requestAnimationFrame(() => scrollToBottom({ animated: false }));
|
|
5649
|
+
return () => cancelAnimationFrame(id);
|
|
5650
|
+
}, [bottomInset, scrollToBottom]);
|
|
5573
5651
|
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
5574
5652
|
import_bottom_sheet5.BottomSheetFlatList,
|
|
5575
5653
|
{
|
|
5576
5654
|
ref: listRef,
|
|
5577
5655
|
data: messages,
|
|
5578
5656
|
keyExtractor: (m) => m.id,
|
|
5657
|
+
keyboardDismissMode: import_react_native44.Platform.OS === "ios" ? "interactive" : "on-drag",
|
|
5658
|
+
keyboardShouldPersistTaps: "handled",
|
|
5579
5659
|
onScroll: handleScroll,
|
|
5580
5660
|
scrollEventThrottle: 16,
|
|
5581
5661
|
showsVerticalScrollIndicator: false,
|
|
@@ -5583,13 +5663,15 @@ var ChatMessageList = React32.forwardRef(
|
|
|
5583
5663
|
{
|
|
5584
5664
|
paddingHorizontal: theme.spacing.lg,
|
|
5585
5665
|
paddingTop: theme.spacing.sm,
|
|
5586
|
-
paddingBottom: theme.spacing.
|
|
5666
|
+
paddingBottom: theme.spacing.sm
|
|
5587
5667
|
},
|
|
5588
5668
|
contentStyle
|
|
5589
5669
|
],
|
|
5590
|
-
renderItem: ({ item, index }) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
5591
|
-
ListFooterComponent:
|
|
5592
|
-
|
|
5670
|
+
renderItem: ({ item, index }) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native44.View, { style: { marginTop: index === 0 ? 0 : theme.spacing.sm }, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChatMessageBubble, { message: item, renderContent: renderMessageContent }) }),
|
|
5671
|
+
ListFooterComponent: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_react_native44.View, { children: [
|
|
5672
|
+
showTypingIndicator ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native44.View, { style: { marginTop: theme.spacing.sm, alignSelf: "flex-start", paddingHorizontal: theme.spacing.lg }, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(TypingIndicator, {}) }) : null,
|
|
5673
|
+
bottomInset > 0 ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native44.View, { style: { height: bottomInset } }) : null
|
|
5674
|
+
] })
|
|
5593
5675
|
}
|
|
5594
5676
|
);
|
|
5595
5677
|
}
|
|
@@ -5612,63 +5694,65 @@ function ChatPage({
|
|
|
5612
5694
|
}) {
|
|
5613
5695
|
const theme = useTheme();
|
|
5614
5696
|
const insets = (0, import_react_native_safe_area_context4.useSafeAreaInsets)();
|
|
5615
|
-
const [composerHeight, setComposerHeight] =
|
|
5616
|
-
const [keyboardVisible, setKeyboardVisible] =
|
|
5617
|
-
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
const
|
|
5621
|
-
const hide = import_react_native44.Keyboard.addListener("keyboardWillHide", () => setKeyboardVisible(false));
|
|
5697
|
+
const [composerHeight, setComposerHeight] = React34.useState(0);
|
|
5698
|
+
const [keyboardVisible, setKeyboardVisible] = React34.useState(false);
|
|
5699
|
+
React34.useEffect(() => {
|
|
5700
|
+
if (import_react_native45.Platform.OS !== "ios") return;
|
|
5701
|
+
const show = import_react_native45.Keyboard.addListener("keyboardWillShow", () => setKeyboardVisible(true));
|
|
5702
|
+
const hide = import_react_native45.Keyboard.addListener("keyboardWillHide", () => setKeyboardVisible(false));
|
|
5622
5703
|
return () => {
|
|
5623
5704
|
show.remove();
|
|
5624
5705
|
hide.remove();
|
|
5625
5706
|
};
|
|
5626
5707
|
}, []);
|
|
5627
|
-
const footerBottomPadding =
|
|
5628
|
-
const footerAnimatedStyle = (0, import_react_native_reanimated2.useAnimatedStyle)(() => {
|
|
5629
|
-
if (import_react_native44.Platform.OS !== "ios") return { paddingBottom: insets.bottom + 10 };
|
|
5630
|
-
return { paddingBottom: animatedKeyboard.height.value > 0 ? 0 : insets.bottom };
|
|
5631
|
-
});
|
|
5708
|
+
const footerBottomPadding = import_react_native45.Platform.OS === "ios" ? keyboardVisible ? 0 : insets.bottom : insets.bottom + 10;
|
|
5632
5709
|
const overlayBottom = composerHeight + footerBottomPadding + theme.spacing.lg;
|
|
5633
|
-
const
|
|
5710
|
+
const bottomInset = composerHeight + footerBottomPadding + theme.spacing.xl;
|
|
5711
|
+
const resolvedOverlay = React34.useMemo(() => {
|
|
5634
5712
|
var _a;
|
|
5635
5713
|
if (!overlay) return null;
|
|
5636
|
-
if (!
|
|
5714
|
+
if (!React34.isValidElement(overlay)) return overlay;
|
|
5637
5715
|
const prevStyle = (_a = overlay.props) == null ? void 0 : _a.style;
|
|
5638
|
-
return
|
|
5716
|
+
return React34.cloneElement(overlay, {
|
|
5639
5717
|
style: [prevStyle, { bottom: overlayBottom }]
|
|
5640
5718
|
});
|
|
5641
5719
|
}, [overlay, overlayBottom]);
|
|
5642
|
-
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
5643
|
-
header ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
5644
|
-
topBanner ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
5645
|
-
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
5646
|
-
/* @__PURE__ */ (0, import_jsx_runtime47.
|
|
5647
|
-
|
|
5720
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native45.View, { style: [{ flex: 1 }, style], children: [
|
|
5721
|
+
header ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native45.View, { children: header }) : null,
|
|
5722
|
+
topBanner ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native45.View, { style: { paddingHorizontal: theme.spacing.lg, paddingTop: theme.spacing.sm }, children: topBanner }) : null,
|
|
5723
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native45.View, { style: { flex: 1 }, children: [
|
|
5724
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
5725
|
+
import_react_native45.View,
|
|
5648
5726
|
{
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5727
|
+
style: { flex: 1 },
|
|
5728
|
+
children: [
|
|
5729
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
5730
|
+
ChatMessageList,
|
|
5731
|
+
{
|
|
5732
|
+
ref: listRef,
|
|
5733
|
+
messages,
|
|
5734
|
+
showTypingIndicator,
|
|
5735
|
+
renderMessageContent,
|
|
5736
|
+
onNearBottomChange,
|
|
5737
|
+
bottomInset
|
|
5738
|
+
}
|
|
5739
|
+
),
|
|
5740
|
+
resolvedOverlay
|
|
5741
|
+
]
|
|
5655
5742
|
}
|
|
5656
5743
|
),
|
|
5657
|
-
resolvedOverlay,
|
|
5658
5744
|
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
5659
|
-
|
|
5745
|
+
import_react_native45.View,
|
|
5660
5746
|
{
|
|
5661
|
-
style:
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
footerAnimatedStyle
|
|
5671
|
-
],
|
|
5747
|
+
style: {
|
|
5748
|
+
position: "absolute",
|
|
5749
|
+
left: 0,
|
|
5750
|
+
right: 0,
|
|
5751
|
+
bottom: 0,
|
|
5752
|
+
paddingHorizontal: theme.spacing.lg,
|
|
5753
|
+
paddingTop: theme.spacing.sm,
|
|
5754
|
+
paddingBottom: footerBottomPadding
|
|
5755
|
+
},
|
|
5672
5756
|
children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
5673
5757
|
ChatComposer,
|
|
5674
5758
|
{
|
|
@@ -5684,25 +5768,25 @@ function ChatPage({
|
|
|
5684
5768
|
}
|
|
5685
5769
|
|
|
5686
5770
|
// src/components/chat/ScrollToBottomButton.tsx
|
|
5687
|
-
var
|
|
5688
|
-
var
|
|
5689
|
-
var
|
|
5771
|
+
var React35 = __toESM(require("react"));
|
|
5772
|
+
var import_react_native46 = require("react-native");
|
|
5773
|
+
var import_react_native_reanimated2 = __toESM(require("react-native-reanimated"));
|
|
5690
5774
|
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
5691
5775
|
function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
5692
5776
|
const theme = useTheme();
|
|
5693
|
-
const progress = (0,
|
|
5694
|
-
const [pressed, setPressed] =
|
|
5695
|
-
|
|
5696
|
-
progress.value = (0,
|
|
5777
|
+
const progress = (0, import_react_native_reanimated2.useSharedValue)(visible ? 1 : 0);
|
|
5778
|
+
const [pressed, setPressed] = React35.useState(false);
|
|
5779
|
+
React35.useEffect(() => {
|
|
5780
|
+
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) });
|
|
5697
5781
|
}, [progress, visible]);
|
|
5698
|
-
const animStyle = (0,
|
|
5782
|
+
const animStyle = (0, import_react_native_reanimated2.useAnimatedStyle)(() => ({
|
|
5699
5783
|
opacity: progress.value,
|
|
5700
5784
|
transform: [{ translateY: (1 - progress.value) * 20 }]
|
|
5701
5785
|
}));
|
|
5702
5786
|
const bg = theme.scheme === "dark" ? "rgba(39,39,42,0.9)" : "rgba(244,244,245,0.95)";
|
|
5703
5787
|
const border = theme.scheme === "dark" ? withAlpha("#FFFFFF", 0.12) : withAlpha("#000000", 0.08);
|
|
5704
5788
|
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
5705
|
-
|
|
5789
|
+
import_react_native_reanimated2.default.View,
|
|
5706
5790
|
{
|
|
5707
5791
|
pointerEvents: visible ? "auto" : "none",
|
|
5708
5792
|
style: [
|
|
@@ -5716,7 +5800,7 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5716
5800
|
animStyle
|
|
5717
5801
|
],
|
|
5718
5802
|
children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
5719
|
-
|
|
5803
|
+
import_react_native46.View,
|
|
5720
5804
|
{
|
|
5721
5805
|
style: {
|
|
5722
5806
|
width: 44,
|
|
@@ -5735,7 +5819,7 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5735
5819
|
opacity: pressed ? 0.85 : 1
|
|
5736
5820
|
},
|
|
5737
5821
|
children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
5738
|
-
|
|
5822
|
+
import_react_native46.Pressable,
|
|
5739
5823
|
{
|
|
5740
5824
|
onPress,
|
|
5741
5825
|
onPressIn: () => setPressed(true),
|
|
@@ -5752,10 +5836,10 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5752
5836
|
}
|
|
5753
5837
|
|
|
5754
5838
|
// src/components/chat/ChatHeader.tsx
|
|
5755
|
-
var
|
|
5839
|
+
var import_react_native47 = require("react-native");
|
|
5756
5840
|
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
5757
5841
|
function ChatHeader({ left, right, center, style }) {
|
|
5758
|
-
const flattenedStyle =
|
|
5842
|
+
const flattenedStyle = import_react_native47.StyleSheet.flatten([
|
|
5759
5843
|
{
|
|
5760
5844
|
paddingTop: 0
|
|
5761
5845
|
},
|
|
@@ -5773,7 +5857,7 @@ function ChatHeader({ left, right, center, style }) {
|
|
|
5773
5857
|
}
|
|
5774
5858
|
|
|
5775
5859
|
// src/components/chat/ForkNoticeBanner.tsx
|
|
5776
|
-
var
|
|
5860
|
+
var import_react_native48 = require("react-native");
|
|
5777
5861
|
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
5778
5862
|
function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
5779
5863
|
const theme = useTheme();
|
|
@@ -5794,7 +5878,7 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
|
5794
5878
|
},
|
|
5795
5879
|
style
|
|
5796
5880
|
],
|
|
5797
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
5881
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_react_native48.View, { style: { minWidth: 0 }, children: [
|
|
5798
5882
|
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
5799
5883
|
Text,
|
|
5800
5884
|
{
|
|
@@ -5847,32 +5931,34 @@ function ChatPanel({
|
|
|
5847
5931
|
onStartDraw,
|
|
5848
5932
|
onSend
|
|
5849
5933
|
}) {
|
|
5850
|
-
const listRef =
|
|
5851
|
-
const [nearBottom, setNearBottom] =
|
|
5852
|
-
const handleSend =
|
|
5934
|
+
const listRef = React36.useRef(null);
|
|
5935
|
+
const [nearBottom, setNearBottom] = React36.useState(true);
|
|
5936
|
+
const handleSend = React36.useCallback(
|
|
5853
5937
|
async (text, composerAttachments) => {
|
|
5854
5938
|
const all = composerAttachments ?? attachments;
|
|
5855
5939
|
await onSend(text, all.length > 0 ? all : void 0);
|
|
5856
5940
|
onClearAttachments == null ? void 0 : onClearAttachments();
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5941
|
+
if (!nearBottom) {
|
|
5942
|
+
requestAnimationFrame(() => {
|
|
5943
|
+
var _a;
|
|
5944
|
+
return (_a = listRef.current) == null ? void 0 : _a.scrollToBottom({ animated: true });
|
|
5945
|
+
});
|
|
5946
|
+
}
|
|
5861
5947
|
},
|
|
5862
|
-
[attachments, onClearAttachments, onSend]
|
|
5948
|
+
[attachments, nearBottom, onClearAttachments, onSend]
|
|
5863
5949
|
);
|
|
5864
|
-
const handleScrollToBottom =
|
|
5950
|
+
const handleScrollToBottom = React36.useCallback(() => {
|
|
5865
5951
|
var _a;
|
|
5866
5952
|
(_a = listRef.current) == null ? void 0 : _a.scrollToBottom({ animated: true });
|
|
5867
5953
|
}, []);
|
|
5868
5954
|
const header = /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
5869
5955
|
ChatHeader,
|
|
5870
5956
|
{
|
|
5871
|
-
left: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
5957
|
+
left: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native49.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5872
5958
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StudioSheetHeaderIconButton, { onPress: onBack, accessibilityLabel: "Back", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconBack, { size: 20, colorToken: "floatingContent" }) }),
|
|
5873
5959
|
onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconHome, { size: 20, colorToken: "floatingContent" }) }) : null
|
|
5874
5960
|
] }),
|
|
5875
|
-
right: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
5961
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native49.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5876
5962
|
onStartDraw ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StudioSheetHeaderIconButton, { onPress: onStartDraw, accessibilityLabel: "Draw", intent: "danger", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconDraw, { size: 20, colorToken: "onDanger" }) }) : null,
|
|
5877
5963
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconClose, { size: 20, colorToken: "floatingContent" }) })
|
|
5878
5964
|
] }),
|
|
@@ -5888,12 +5974,12 @@ function ChatPanel({
|
|
|
5888
5974
|
) : null;
|
|
5889
5975
|
const showMessagesLoading = Boolean(loading) && messages.length === 0 || forking;
|
|
5890
5976
|
if (showMessagesLoading) {
|
|
5891
|
-
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
5892
|
-
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
5893
|
-
topBanner ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
5894
|
-
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
5895
|
-
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
5896
|
-
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
5977
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native49.View, { style: { flex: 1 }, children: [
|
|
5978
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native49.View, { children: header }),
|
|
5979
|
+
topBanner ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native49.View, { style: { paddingHorizontal: 16, paddingTop: 8 }, children: topBanner }) : null,
|
|
5980
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native49.View, { style: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 24, paddingVertical: 12 }, children: [
|
|
5981
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native49.ActivityIndicator, {}),
|
|
5982
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native49.View, { style: { height: 12 } }),
|
|
5897
5983
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Text, { variant: "bodyMuted", children: forking ? "Creating your copy\u2026" : "Loading messages\u2026" })
|
|
5898
5984
|
] })
|
|
5899
5985
|
] });
|
|
@@ -5917,7 +6003,10 @@ function ChatPanel({
|
|
|
5917
6003
|
}
|
|
5918
6004
|
),
|
|
5919
6005
|
composer: {
|
|
5920
|
-
|
|
6006
|
+
// Keep the input editable even when sending is disallowed (e.g. agent still working),
|
|
6007
|
+
// otherwise iOS will drop focus/keyboard and BottomSheet can get "stuck" with a keyboard-sized gap.
|
|
6008
|
+
disabled: Boolean(loading) || Boolean(forking),
|
|
6009
|
+
sendDisabled: Boolean(sendDisabled) || Boolean(loading) || Boolean(forking),
|
|
5921
6010
|
sending: Boolean(sending),
|
|
5922
6011
|
autoFocus: autoFocusComposer,
|
|
5923
6012
|
onSend: handleSend,
|
|
@@ -5931,11 +6020,11 @@ function ChatPanel({
|
|
|
5931
6020
|
}
|
|
5932
6021
|
|
|
5933
6022
|
// src/components/dialogs/ConfirmMergeRequestDialog.tsx
|
|
5934
|
-
var
|
|
5935
|
-
var
|
|
6023
|
+
var React37 = __toESM(require("react"));
|
|
6024
|
+
var import_react_native51 = require("react-native");
|
|
5936
6025
|
|
|
5937
6026
|
// src/components/primitives/Modal.tsx
|
|
5938
|
-
var
|
|
6027
|
+
var import_react_native50 = require("react-native");
|
|
5939
6028
|
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
5940
6029
|
function Modal({
|
|
5941
6030
|
visible,
|
|
@@ -5946,15 +6035,15 @@ function Modal({
|
|
|
5946
6035
|
}) {
|
|
5947
6036
|
const theme = useTheme();
|
|
5948
6037
|
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
5949
|
-
|
|
6038
|
+
import_react_native50.Modal,
|
|
5950
6039
|
{
|
|
5951
6040
|
visible,
|
|
5952
6041
|
transparent: true,
|
|
5953
6042
|
animationType: "fade",
|
|
5954
6043
|
onRequestClose,
|
|
5955
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
6044
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_react_native50.View, { style: { flex: 1, backgroundColor: theme.colors.backdrop, justifyContent: "center", padding: theme.spacing.lg }, children: [
|
|
5956
6045
|
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
5957
|
-
|
|
6046
|
+
import_react_native50.Pressable,
|
|
5958
6047
|
{
|
|
5959
6048
|
accessibilityRole: "button",
|
|
5960
6049
|
onPress: dismissOnBackdropPress ? onRequestClose : void 0,
|
|
@@ -5979,14 +6068,14 @@ function ConfirmMergeRequestDialog({
|
|
|
5979
6068
|
onTestFirst
|
|
5980
6069
|
}) {
|
|
5981
6070
|
const theme = useTheme();
|
|
5982
|
-
const close =
|
|
6071
|
+
const close = React37.useCallback(() => onOpenChange(false), [onOpenChange]);
|
|
5983
6072
|
const canConfirm = Boolean(mergeRequest) && !approveDisabled;
|
|
5984
|
-
const handleConfirm =
|
|
6073
|
+
const handleConfirm = React37.useCallback(() => {
|
|
5985
6074
|
if (!mergeRequest) return;
|
|
5986
6075
|
onOpenChange(false);
|
|
5987
6076
|
void onConfirm();
|
|
5988
6077
|
}, [mergeRequest, onConfirm, onOpenChange]);
|
|
5989
|
-
const handleTestFirst =
|
|
6078
|
+
const handleTestFirst = React37.useCallback(() => {
|
|
5990
6079
|
if (!mergeRequest) return;
|
|
5991
6080
|
onOpenChange(false);
|
|
5992
6081
|
void onTestFirst(mergeRequest);
|
|
@@ -6009,7 +6098,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6009
6098
|
backgroundColor: theme.colors.background
|
|
6010
6099
|
},
|
|
6011
6100
|
children: [
|
|
6012
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6101
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.View, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6013
6102
|
Text,
|
|
6014
6103
|
{
|
|
6015
6104
|
style: {
|
|
@@ -6021,9 +6110,9 @@ function ConfirmMergeRequestDialog({
|
|
|
6021
6110
|
children: "Are you sure you want to approve this merge request?"
|
|
6022
6111
|
}
|
|
6023
6112
|
) }),
|
|
6024
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
6113
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_native51.View, { style: { marginTop: 16 }, children: [
|
|
6025
6114
|
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6026
|
-
|
|
6115
|
+
import_react_native51.View,
|
|
6027
6116
|
{
|
|
6028
6117
|
style: [
|
|
6029
6118
|
fullWidthButtonBase,
|
|
@@ -6033,7 +6122,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6033
6122
|
}
|
|
6034
6123
|
],
|
|
6035
6124
|
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6036
|
-
|
|
6125
|
+
import_react_native51.Pressable,
|
|
6037
6126
|
{
|
|
6038
6127
|
accessibilityRole: "button",
|
|
6039
6128
|
accessibilityLabel: "Approve Merge",
|
|
@@ -6045,9 +6134,9 @@ function ConfirmMergeRequestDialog({
|
|
|
6045
6134
|
)
|
|
6046
6135
|
}
|
|
6047
6136
|
),
|
|
6048
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6137
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.View, { style: { height: 8 } }),
|
|
6049
6138
|
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6050
|
-
|
|
6139
|
+
import_react_native51.View,
|
|
6051
6140
|
{
|
|
6052
6141
|
style: [
|
|
6053
6142
|
fullWidthButtonBase,
|
|
@@ -6059,7 +6148,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6059
6148
|
}
|
|
6060
6149
|
],
|
|
6061
6150
|
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6062
|
-
|
|
6151
|
+
import_react_native51.Pressable,
|
|
6063
6152
|
{
|
|
6064
6153
|
accessibilityRole: "button",
|
|
6065
6154
|
accessibilityLabel: isBuilding ? "Preparing\u2026" : "Test edits first",
|
|
@@ -6071,9 +6160,9 @@ function ConfirmMergeRequestDialog({
|
|
|
6071
6160
|
)
|
|
6072
6161
|
}
|
|
6073
6162
|
),
|
|
6074
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6163
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.View, { style: { height: 8 } }),
|
|
6075
6164
|
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6076
|
-
|
|
6165
|
+
import_react_native51.View,
|
|
6077
6166
|
{
|
|
6078
6167
|
style: [
|
|
6079
6168
|
fullWidthButtonBase,
|
|
@@ -6084,7 +6173,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6084
6173
|
}
|
|
6085
6174
|
],
|
|
6086
6175
|
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6087
|
-
|
|
6176
|
+
import_react_native51.Pressable,
|
|
6088
6177
|
{
|
|
6089
6178
|
accessibilityRole: "button",
|
|
6090
6179
|
accessibilityLabel: "Cancel",
|
|
@@ -6165,30 +6254,33 @@ function StudioOverlay({
|
|
|
6165
6254
|
onNavigateHome
|
|
6166
6255
|
}) {
|
|
6167
6256
|
const theme = useTheme();
|
|
6168
|
-
const { width } = (0,
|
|
6169
|
-
const [sheetOpen, setSheetOpen] =
|
|
6170
|
-
const [activePage, setActivePage] =
|
|
6171
|
-
const [drawing, setDrawing] =
|
|
6172
|
-
const [chatAttachments, setChatAttachments] =
|
|
6173
|
-
const [commentsAppId, setCommentsAppId] =
|
|
6174
|
-
const [commentsCount, setCommentsCount] =
|
|
6175
|
-
const [confirmMrId, setConfirmMrId] =
|
|
6176
|
-
const confirmMr =
|
|
6257
|
+
const { width } = (0, import_react_native52.useWindowDimensions)();
|
|
6258
|
+
const [sheetOpen, setSheetOpen] = React38.useState(false);
|
|
6259
|
+
const [activePage, setActivePage] = React38.useState("preview");
|
|
6260
|
+
const [drawing, setDrawing] = React38.useState(false);
|
|
6261
|
+
const [chatAttachments, setChatAttachments] = React38.useState([]);
|
|
6262
|
+
const [commentsAppId, setCommentsAppId] = React38.useState(null);
|
|
6263
|
+
const [commentsCount, setCommentsCount] = React38.useState(null);
|
|
6264
|
+
const [confirmMrId, setConfirmMrId] = React38.useState(null);
|
|
6265
|
+
const confirmMr = React38.useMemo(
|
|
6177
6266
|
() => confirmMrId ? incomingMergeRequests.find((m) => m.id === confirmMrId) ?? null : null,
|
|
6178
6267
|
[confirmMrId, incomingMergeRequests]
|
|
6179
6268
|
);
|
|
6180
|
-
const
|
|
6181
|
-
setSheetOpen(
|
|
6182
|
-
|
|
6269
|
+
const handleSheetOpenChange = React38.useCallback((open) => {
|
|
6270
|
+
setSheetOpen(open);
|
|
6271
|
+
if (!open) import_react_native52.Keyboard.dismiss();
|
|
6183
6272
|
}, []);
|
|
6184
|
-
const
|
|
6185
|
-
|
|
6273
|
+
const closeSheet = React38.useCallback(() => {
|
|
6274
|
+
handleSheetOpenChange(false);
|
|
6275
|
+
}, [handleSheetOpenChange]);
|
|
6276
|
+
const openSheet = React38.useCallback(() => setSheetOpen(true), []);
|
|
6277
|
+
const goToChat = React38.useCallback(() => {
|
|
6186
6278
|
setActivePage("chat");
|
|
6187
6279
|
openSheet();
|
|
6188
6280
|
}, [openSheet]);
|
|
6189
|
-
const backToPreview =
|
|
6190
|
-
if (
|
|
6191
|
-
|
|
6281
|
+
const backToPreview = React38.useCallback(() => {
|
|
6282
|
+
if (import_react_native52.Platform.OS !== "ios") {
|
|
6283
|
+
import_react_native52.Keyboard.dismiss();
|
|
6192
6284
|
setActivePage("preview");
|
|
6193
6285
|
return;
|
|
6194
6286
|
}
|
|
@@ -6200,15 +6292,15 @@ function StudioOverlay({
|
|
|
6200
6292
|
clearTimeout(t);
|
|
6201
6293
|
setActivePage("preview");
|
|
6202
6294
|
};
|
|
6203
|
-
const sub =
|
|
6295
|
+
const sub = import_react_native52.Keyboard.addListener("keyboardDidHide", finalize);
|
|
6204
6296
|
const t = setTimeout(finalize, 350);
|
|
6205
|
-
|
|
6297
|
+
import_react_native52.Keyboard.dismiss();
|
|
6206
6298
|
}, []);
|
|
6207
|
-
const startDraw =
|
|
6299
|
+
const startDraw = React38.useCallback(() => {
|
|
6208
6300
|
setDrawing(true);
|
|
6209
6301
|
closeSheet();
|
|
6210
6302
|
}, [closeSheet]);
|
|
6211
|
-
const handleDrawCapture =
|
|
6303
|
+
const handleDrawCapture = React38.useCallback(
|
|
6212
6304
|
(dataUrl) => {
|
|
6213
6305
|
setChatAttachments((prev) => [...prev, dataUrl]);
|
|
6214
6306
|
setDrawing(false);
|
|
@@ -6217,7 +6309,7 @@ function StudioOverlay({
|
|
|
6217
6309
|
},
|
|
6218
6310
|
[openSheet]
|
|
6219
6311
|
);
|
|
6220
|
-
const toggleSheet =
|
|
6312
|
+
const toggleSheet = React38.useCallback(async () => {
|
|
6221
6313
|
if (!sheetOpen) {
|
|
6222
6314
|
const shouldExitTest = Boolean(testingMrId) || isTesting;
|
|
6223
6315
|
if (shouldExitTest) {
|
|
@@ -6229,7 +6321,7 @@ function StudioOverlay({
|
|
|
6229
6321
|
closeSheet();
|
|
6230
6322
|
}
|
|
6231
6323
|
}, [closeSheet, isTesting, onRestoreBase, sheetOpen, testingMrId]);
|
|
6232
|
-
const handleTestMr =
|
|
6324
|
+
const handleTestMr = React38.useCallback(
|
|
6233
6325
|
async (mr) => {
|
|
6234
6326
|
if (!onTestMr) return;
|
|
6235
6327
|
await onTestMr(mr);
|
|
@@ -6239,7 +6331,7 @@ function StudioOverlay({
|
|
|
6239
6331
|
);
|
|
6240
6332
|
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
|
|
6241
6333
|
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(EdgeGlowFrame, { visible: isTesting, role: "accent", thickness: 40, intensity: 1 }),
|
|
6242
|
-
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(StudioBottomSheet, { open: sheetOpen, onOpenChange:
|
|
6334
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(StudioBottomSheet, { open: sheetOpen, onOpenChange: handleSheetOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6243
6335
|
StudioSheetPager,
|
|
6244
6336
|
{
|
|
6245
6337
|
activePage,
|
|
@@ -6301,7 +6393,7 @@ function StudioOverlay({
|
|
|
6301
6393
|
badgeCount: incomingMergeRequests.length,
|
|
6302
6394
|
onPress: toggleSheet,
|
|
6303
6395
|
isLoading: (app == null ? void 0 : app.status) === "editing",
|
|
6304
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6396
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react_native52.View, { style: { width: 28, height: 28, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(MergeIcon, { width: 24, height: 24, color: theme.colors.floatingContent }) })
|
|
6305
6397
|
}
|
|
6306
6398
|
),
|
|
6307
6399
|
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
@@ -6347,16 +6439,16 @@ function ComergeStudio({
|
|
|
6347
6439
|
onNavigateHome,
|
|
6348
6440
|
style
|
|
6349
6441
|
}) {
|
|
6350
|
-
const [activeAppId, setActiveAppId] =
|
|
6351
|
-
const [runtimeAppId, setRuntimeAppId] =
|
|
6352
|
-
const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] =
|
|
6353
|
-
const platform =
|
|
6354
|
-
|
|
6442
|
+
const [activeAppId, setActiveAppId] = React39.useState(appId);
|
|
6443
|
+
const [runtimeAppId, setRuntimeAppId] = React39.useState(appId);
|
|
6444
|
+
const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] = React39.useState(null);
|
|
6445
|
+
const platform = React39.useMemo(() => import_react_native53.Platform.OS === "ios" ? "ios" : "android", []);
|
|
6446
|
+
React39.useEffect(() => {
|
|
6355
6447
|
setActiveAppId(appId);
|
|
6356
6448
|
setRuntimeAppId(appId);
|
|
6357
6449
|
setPendingRuntimeTargetAppId(null);
|
|
6358
6450
|
}, [appId]);
|
|
6359
|
-
const captureTargetRef =
|
|
6451
|
+
const captureTargetRef = React39.useRef(null);
|
|
6360
6452
|
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(StudioBootstrap, { apiKey, children: ({ userId }) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_bottom_sheet6.BottomSheetModalProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
6361
6453
|
ComergeStudioInner,
|
|
6362
6454
|
{
|
|
@@ -6392,11 +6484,11 @@ function ComergeStudioInner({
|
|
|
6392
6484
|
const { app, loading: appLoading } = useApp(activeAppId);
|
|
6393
6485
|
const { app: runtimeAppFromHook } = useApp(runtimeAppId, { enabled: runtimeAppId !== activeAppId });
|
|
6394
6486
|
const runtimeApp = runtimeAppId === activeAppId ? app : runtimeAppFromHook;
|
|
6395
|
-
const sawEditingOnPendingTargetRef =
|
|
6396
|
-
|
|
6487
|
+
const sawEditingOnPendingTargetRef = React39.useRef(false);
|
|
6488
|
+
React39.useEffect(() => {
|
|
6397
6489
|
sawEditingOnPendingTargetRef.current = false;
|
|
6398
6490
|
}, [pendingRuntimeTargetAppId]);
|
|
6399
|
-
|
|
6491
|
+
React39.useEffect(() => {
|
|
6400
6492
|
if (!pendingRuntimeTargetAppId) return;
|
|
6401
6493
|
if (activeAppId !== pendingRuntimeTargetAppId) return;
|
|
6402
6494
|
if ((app == null ? void 0 : app.status) === "editing") {
|
|
@@ -6416,10 +6508,10 @@ function ComergeStudioInner({
|
|
|
6416
6508
|
const threadId = (app == null ? void 0 : app.threadId) ?? "";
|
|
6417
6509
|
const thread = useThreadMessages(threadId);
|
|
6418
6510
|
const mergeRequests = useMergeRequests({ appId: activeAppId });
|
|
6419
|
-
const hasOpenOutgoingMr =
|
|
6511
|
+
const hasOpenOutgoingMr = React39.useMemo(() => {
|
|
6420
6512
|
return mergeRequests.lists.outgoing.some((mr) => mr.status === "open");
|
|
6421
6513
|
}, [mergeRequests.lists.outgoing]);
|
|
6422
|
-
const incomingReviewMrs =
|
|
6514
|
+
const incomingReviewMrs = React39.useMemo(() => {
|
|
6423
6515
|
if (!userId) return mergeRequests.lists.incoming;
|
|
6424
6516
|
return mergeRequests.lists.incoming.filter((mr) => mr.createdBy !== userId);
|
|
6425
6517
|
}, [mergeRequests.lists.incoming, userId]);
|
|
@@ -6441,16 +6533,16 @@ function ComergeStudioInner({
|
|
|
6441
6533
|
uploadAttachments: uploader.uploadBase64Images
|
|
6442
6534
|
});
|
|
6443
6535
|
const chatSendDisabled = hasNoOutcomeAfterLastHuman(thread.raw);
|
|
6444
|
-
const [processingMrId, setProcessingMrId] =
|
|
6445
|
-
const [testingMrId, setTestingMrId] =
|
|
6446
|
-
const chatShowTypingIndicator =
|
|
6536
|
+
const [processingMrId, setProcessingMrId] = React39.useState(null);
|
|
6537
|
+
const [testingMrId, setTestingMrId] = React39.useState(null);
|
|
6538
|
+
const chatShowTypingIndicator = React39.useMemo(() => {
|
|
6447
6539
|
var _a;
|
|
6448
6540
|
if (!thread.raw || thread.raw.length === 0) return false;
|
|
6449
6541
|
const last = thread.raw[thread.raw.length - 1];
|
|
6450
6542
|
const payloadType = typeof ((_a = last.payload) == null ? void 0 : _a.type) === "string" ? String(last.payload.type) : void 0;
|
|
6451
6543
|
return payloadType !== "outcome";
|
|
6452
6544
|
}, [thread.raw]);
|
|
6453
|
-
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
6545
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_react_native53.View, { style: [{ flex: 1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_react_native53.View, { ref: captureTargetRef, style: { flex: 1 }, collapsable: false, children: [
|
|
6454
6546
|
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(RuntimeRenderer, { appKey, bundlePath: bundle.bundlePath, renderToken: bundle.renderToken }),
|
|
6455
6547
|
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
6456
6548
|
StudioOverlay,
|