@comergehq/studio 0.1.6 → 0.1.8
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 +675 -576
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +423 -324
- 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 +26 -9
- package/src/components/chat/ChatPage.tsx +2 -1
- package/src/components/comments/AppCommentsSheet.tsx +6 -1
- package/src/components/comments/useIosKeyboardSnapFix.ts +11 -3
- package/src/components/studio-sheet/StudioBottomSheet.tsx +33 -5
- 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/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,43 @@ 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;
|
|
1799
|
+
const sheet = resolvedSheetRef.current;
|
|
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
|
+
}
|
|
1807
|
+
});
|
|
1808
|
+
return () => sub.remove();
|
|
1809
|
+
}, [open, resolvedSheetRef]);
|
|
1810
|
+
React9.useEffect(() => {
|
|
1811
|
+
if (import_react_native7.Platform.OS !== "ios") return;
|
|
1812
|
+
const sub = import_react_native7.Keyboard.addListener("keyboardDidHide", () => {
|
|
1746
1813
|
const sheet = resolvedSheetRef.current;
|
|
1747
1814
|
if (!sheet || !open) return;
|
|
1748
1815
|
const targetIndex = snapPoints.length - 1;
|
|
1749
|
-
|
|
1816
|
+
if (currentIndexRef.current === targetIndex) {
|
|
1817
|
+
setTimeout(() => sheet.snapToIndex(targetIndex), 10);
|
|
1818
|
+
}
|
|
1750
1819
|
});
|
|
1751
1820
|
return () => sub.remove();
|
|
1752
1821
|
}, [open, resolvedSheetRef, snapPoints.length]);
|
|
1753
|
-
|
|
1822
|
+
React9.useEffect(() => {
|
|
1754
1823
|
const sheet = resolvedSheetRef.current;
|
|
1755
1824
|
if (!sheet) return;
|
|
1756
1825
|
if (open) {
|
|
@@ -1759,8 +1828,9 @@ function StudioBottomSheet({
|
|
|
1759
1828
|
sheet.close();
|
|
1760
1829
|
}
|
|
1761
1830
|
}, [open, resolvedSheetRef, snapPoints.length]);
|
|
1762
|
-
const handleChange =
|
|
1831
|
+
const handleChange = React9.useCallback(
|
|
1763
1832
|
(index) => {
|
|
1833
|
+
currentIndexRef.current = index;
|
|
1764
1834
|
onOpenChange == null ? void 0 : onOpenChange(index >= 0);
|
|
1765
1835
|
},
|
|
1766
1836
|
[onOpenChange]
|
|
@@ -1772,7 +1842,7 @@ function StudioBottomSheet({
|
|
|
1772
1842
|
index: open ? snapPoints.length - 1 : -1,
|
|
1773
1843
|
snapPoints,
|
|
1774
1844
|
enablePanDownToClose: true,
|
|
1775
|
-
keyboardBehavior:
|
|
1845
|
+
keyboardBehavior: "interactive",
|
|
1776
1846
|
keyboardBlurBehavior: "restore",
|
|
1777
1847
|
android_keyboardInputMode: "adjustResize",
|
|
1778
1848
|
backgroundComponent: (props) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StudioSheetBackground, { ...props, renderBackground: background == null ? void 0 : background.renderBackground }),
|
|
@@ -1781,19 +1851,19 @@ function StudioBottomSheet({
|
|
|
1781
1851
|
handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
|
|
1782
1852
|
onChange: handleChange,
|
|
1783
1853
|
...bottomSheetProps,
|
|
1784
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1854
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native7.View, { style: { flex: 1, overflow: "hidden" }, children })
|
|
1785
1855
|
}
|
|
1786
1856
|
);
|
|
1787
1857
|
}
|
|
1788
1858
|
|
|
1789
1859
|
// src/components/studio-sheet/StudioSheetPager.tsx
|
|
1790
|
-
var
|
|
1791
|
-
var
|
|
1860
|
+
var React10 = __toESM(require("react"));
|
|
1861
|
+
var import_react_native8 = require("react-native");
|
|
1792
1862
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1793
1863
|
function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
1794
|
-
const anim =
|
|
1795
|
-
|
|
1796
|
-
|
|
1864
|
+
const anim = React10.useRef(new import_react_native8.Animated.Value(activePage === "chat" ? 1 : 0)).current;
|
|
1865
|
+
React10.useEffect(() => {
|
|
1866
|
+
import_react_native8.Animated.spring(anim, {
|
|
1797
1867
|
toValue: activePage === "chat" ? 1 : 0,
|
|
1798
1868
|
useNativeDriver: true,
|
|
1799
1869
|
tension: 65,
|
|
@@ -1802,9 +1872,9 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1802
1872
|
}, [activePage, anim]);
|
|
1803
1873
|
const previewTranslateX = anim.interpolate({ inputRange: [0, 1], outputRange: [0, -width] });
|
|
1804
1874
|
const chatTranslateX = anim.interpolate({ inputRange: [0, 1], outputRange: [width, 0] });
|
|
1805
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1875
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native8.Animated.View, { style: [{ flex: 1 }, style], children: [
|
|
1806
1876
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1807
|
-
|
|
1877
|
+
import_react_native8.Animated.View,
|
|
1808
1878
|
{
|
|
1809
1879
|
style: [
|
|
1810
1880
|
{
|
|
@@ -1821,7 +1891,7 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1821
1891
|
}
|
|
1822
1892
|
),
|
|
1823
1893
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1824
|
-
|
|
1894
|
+
import_react_native8.Animated.View,
|
|
1825
1895
|
{
|
|
1826
1896
|
style: [
|
|
1827
1897
|
{
|
|
@@ -1842,7 +1912,7 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
|
|
|
1842
1912
|
|
|
1843
1913
|
// src/components/floating-draggable-button/FloatingDraggableButton.tsx
|
|
1844
1914
|
var import_react = require("react");
|
|
1845
|
-
var
|
|
1915
|
+
var import_react_native9 = require("react-native");
|
|
1846
1916
|
var Haptics = __toESM(require("expo-haptics"));
|
|
1847
1917
|
var import_react_native_reanimated = __toESM(require("react-native-reanimated"));
|
|
1848
1918
|
var import_liquid_glass2 = require("@callstack/liquid-glass");
|
|
@@ -1901,7 +1971,7 @@ function FloatingDraggableButton({
|
|
|
1901
1971
|
backgroundColor
|
|
1902
1972
|
}) {
|
|
1903
1973
|
const theme = useTheme();
|
|
1904
|
-
const { width, height } = (0,
|
|
1974
|
+
const { width, height } = (0, import_react_native9.useWindowDimensions)();
|
|
1905
1975
|
const isDanger = variant === "danger";
|
|
1906
1976
|
const onPressRef = (0, import_react.useRef)(onPress);
|
|
1907
1977
|
(0, import_react.useEffect)(() => {
|
|
@@ -2004,7 +2074,7 @@ function FloatingDraggableButton({
|
|
|
2004
2074
|
}
|
|
2005
2075
|
}, [forceShowTrigger, visible, animateIn]);
|
|
2006
2076
|
const panResponder = (0, import_react.useRef)(
|
|
2007
|
-
|
|
2077
|
+
import_react_native9.PanResponder.create({
|
|
2008
2078
|
onStartShouldSetPanResponder: () => true,
|
|
2009
2079
|
onMoveShouldSetPanResponder: () => true,
|
|
2010
2080
|
onPanResponderGrant: () => {
|
|
@@ -2067,24 +2137,24 @@ function FloatingDraggableButton({
|
|
|
2067
2137
|
interactive: true,
|
|
2068
2138
|
effect: "clear",
|
|
2069
2139
|
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2070
|
-
|
|
2140
|
+
import_react_native9.Pressable,
|
|
2071
2141
|
{
|
|
2072
2142
|
onPress: () => {
|
|
2073
2143
|
if (!disabled) animateOut();
|
|
2074
2144
|
},
|
|
2075
2145
|
style: styles.buttonInner,
|
|
2076
2146
|
android_ripple: { color: "rgba(255, 255, 255, 0.3)", borderless: true },
|
|
2077
|
-
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2147
|
+
children: children ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.View, {})
|
|
2078
2148
|
}
|
|
2079
2149
|
)
|
|
2080
2150
|
}
|
|
2081
2151
|
) }),
|
|
2082
|
-
badgeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2152
|
+
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
2153
|
]
|
|
2084
2154
|
}
|
|
2085
2155
|
);
|
|
2086
2156
|
}
|
|
2087
|
-
var styles =
|
|
2157
|
+
var styles = import_react_native9.StyleSheet.create({
|
|
2088
2158
|
floatingButton: {
|
|
2089
2159
|
position: "absolute",
|
|
2090
2160
|
justifyContent: "center",
|
|
@@ -2120,8 +2190,8 @@ var styles = import_react_native8.StyleSheet.create({
|
|
|
2120
2190
|
});
|
|
2121
2191
|
|
|
2122
2192
|
// src/components/overlays/EdgeGlowFrame.tsx
|
|
2123
|
-
var
|
|
2124
|
-
var
|
|
2193
|
+
var React11 = __toESM(require("react"));
|
|
2194
|
+
var import_react_native10 = require("react-native");
|
|
2125
2195
|
var import_expo_linear_gradient = require("expo-linear-gradient");
|
|
2126
2196
|
|
|
2127
2197
|
// src/components/utils/color.ts
|
|
@@ -2163,9 +2233,9 @@ function EdgeGlowFrame({
|
|
|
2163
2233
|
}) {
|
|
2164
2234
|
const theme = useTheme();
|
|
2165
2235
|
const alpha = Math.max(0, Math.min(1, intensity));
|
|
2166
|
-
const anim =
|
|
2167
|
-
|
|
2168
|
-
|
|
2236
|
+
const anim = React11.useRef(new import_react_native10.Animated.Value(visible ? 1 : 0)).current;
|
|
2237
|
+
React11.useEffect(() => {
|
|
2238
|
+
import_react_native10.Animated.timing(anim, {
|
|
2169
2239
|
toValue: visible ? 1 : 0,
|
|
2170
2240
|
duration: 300,
|
|
2171
2241
|
useNativeDriver: true
|
|
@@ -2174,8 +2244,8 @@ function EdgeGlowFrame({
|
|
|
2174
2244
|
const c = baseColor(role, theme);
|
|
2175
2245
|
const strong = withAlpha(c, 0.6 * alpha);
|
|
2176
2246
|
const soft = withAlpha(c, 0.22 * alpha);
|
|
2177
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
2178
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2247
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native10.Animated.View, { pointerEvents: "none", style: [{ position: "absolute", inset: 0, opacity: anim }, style], children: [
|
|
2248
|
+
/* @__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
2249
|
import_expo_linear_gradient.LinearGradient,
|
|
2180
2250
|
{
|
|
2181
2251
|
colors: [strong, soft, "transparent"],
|
|
@@ -2184,7 +2254,7 @@ function EdgeGlowFrame({
|
|
|
2184
2254
|
style: { width: "100%", height: "100%" }
|
|
2185
2255
|
}
|
|
2186
2256
|
) }),
|
|
2187
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2257
|
+
/* @__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
2258
|
import_expo_linear_gradient.LinearGradient,
|
|
2189
2259
|
{
|
|
2190
2260
|
colors: ["transparent", soft, strong],
|
|
@@ -2193,7 +2263,7 @@ function EdgeGlowFrame({
|
|
|
2193
2263
|
style: { width: "100%", height: "100%" }
|
|
2194
2264
|
}
|
|
2195
2265
|
) }),
|
|
2196
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2266
|
+
/* @__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
2267
|
import_expo_linear_gradient.LinearGradient,
|
|
2198
2268
|
{
|
|
2199
2269
|
colors: [strong, soft, "transparent"],
|
|
@@ -2202,7 +2272,7 @@ function EdgeGlowFrame({
|
|
|
2202
2272
|
style: { width: "100%", height: "100%" }
|
|
2203
2273
|
}
|
|
2204
2274
|
) }),
|
|
2205
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
2275
|
+
/* @__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
2276
|
import_expo_linear_gradient.LinearGradient,
|
|
2207
2277
|
{
|
|
2208
2278
|
colors: ["transparent", soft, strong],
|
|
@@ -2215,13 +2285,13 @@ function EdgeGlowFrame({
|
|
|
2215
2285
|
}
|
|
2216
2286
|
|
|
2217
2287
|
// src/components/draw/DrawModeOverlay.tsx
|
|
2218
|
-
var
|
|
2219
|
-
var
|
|
2288
|
+
var React14 = __toESM(require("react"));
|
|
2289
|
+
var import_react_native14 = require("react-native");
|
|
2220
2290
|
var import_react_native_view_shot = require("react-native-view-shot");
|
|
2221
2291
|
|
|
2222
2292
|
// src/components/draw/DrawSurface.tsx
|
|
2223
|
-
var
|
|
2224
|
-
var
|
|
2293
|
+
var React12 = __toESM(require("react"));
|
|
2294
|
+
var import_react_native11 = require("react-native");
|
|
2225
2295
|
var import_react_native_svg = __toESM(require("react-native-svg"));
|
|
2226
2296
|
|
|
2227
2297
|
// src/components/draw/strokes.ts
|
|
@@ -2252,25 +2322,25 @@ function DrawSurface({
|
|
|
2252
2322
|
style,
|
|
2253
2323
|
minDistance = 1
|
|
2254
2324
|
}) {
|
|
2255
|
-
const [renderTick, setRenderTick] =
|
|
2256
|
-
const currentPointsRef =
|
|
2257
|
-
const rafRef =
|
|
2258
|
-
const triggerRender =
|
|
2325
|
+
const [renderTick, setRenderTick] = React12.useState(0);
|
|
2326
|
+
const currentPointsRef = React12.useRef([]);
|
|
2327
|
+
const rafRef = React12.useRef(null);
|
|
2328
|
+
const triggerRender = React12.useCallback(() => {
|
|
2259
2329
|
if (rafRef.current !== null) return;
|
|
2260
2330
|
rafRef.current = requestAnimationFrame(() => {
|
|
2261
2331
|
rafRef.current = null;
|
|
2262
2332
|
setRenderTick((n) => n + 1);
|
|
2263
2333
|
});
|
|
2264
2334
|
}, []);
|
|
2265
|
-
|
|
2335
|
+
React12.useEffect(() => () => {
|
|
2266
2336
|
if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);
|
|
2267
2337
|
}, []);
|
|
2268
|
-
const onStart =
|
|
2338
|
+
const onStart = React12.useCallback((e) => {
|
|
2269
2339
|
const { locationX, locationY } = e.nativeEvent;
|
|
2270
2340
|
currentPointsRef.current = [{ x: locationX, y: locationY }];
|
|
2271
2341
|
triggerRender();
|
|
2272
2342
|
}, [triggerRender]);
|
|
2273
|
-
const onMove =
|
|
2343
|
+
const onMove = React12.useCallback((e, _g) => {
|
|
2274
2344
|
const { locationX, locationY } = e.nativeEvent;
|
|
2275
2345
|
const pts = currentPointsRef.current;
|
|
2276
2346
|
if (pts.length > 0) {
|
|
@@ -2283,7 +2353,7 @@ function DrawSurface({
|
|
|
2283
2353
|
currentPointsRef.current = [...pts, { x: locationX, y: locationY }];
|
|
2284
2354
|
triggerRender();
|
|
2285
2355
|
}, [minDistance, triggerRender]);
|
|
2286
|
-
const onEnd =
|
|
2356
|
+
const onEnd = React12.useCallback(() => {
|
|
2287
2357
|
const points = currentPointsRef.current;
|
|
2288
2358
|
if (points.length > 0) {
|
|
2289
2359
|
onAddStroke({ points, color, width: strokeWidth });
|
|
@@ -2291,8 +2361,8 @@ function DrawSurface({
|
|
|
2291
2361
|
currentPointsRef.current = [];
|
|
2292
2362
|
triggerRender();
|
|
2293
2363
|
}, [color, onAddStroke, strokeWidth, triggerRender]);
|
|
2294
|
-
const panResponder =
|
|
2295
|
-
() =>
|
|
2364
|
+
const panResponder = React12.useMemo(
|
|
2365
|
+
() => import_react_native11.PanResponder.create({
|
|
2296
2366
|
onStartShouldSetPanResponder: () => true,
|
|
2297
2367
|
onMoveShouldSetPanResponder: () => true,
|
|
2298
2368
|
onPanResponderGrant: onStart,
|
|
@@ -2304,7 +2374,7 @@ function DrawSurface({
|
|
|
2304
2374
|
);
|
|
2305
2375
|
const currentPath = pointsToSmoothPath(currentPointsRef.current);
|
|
2306
2376
|
void renderTick;
|
|
2307
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
2377
|
+
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
2378
|
strokes.map((s, idx) => {
|
|
2309
2379
|
const d = pointsToSmoothPath(s.points);
|
|
2310
2380
|
if (!d) return null;
|
|
@@ -2334,15 +2404,15 @@ function DrawSurface({
|
|
|
2334
2404
|
) : null
|
|
2335
2405
|
] }) });
|
|
2336
2406
|
}
|
|
2337
|
-
var styles2 =
|
|
2407
|
+
var styles2 = import_react_native11.StyleSheet.create({
|
|
2338
2408
|
container: {
|
|
2339
2409
|
zIndex: 5
|
|
2340
2410
|
}
|
|
2341
2411
|
});
|
|
2342
2412
|
|
|
2343
2413
|
// src/components/draw/DrawToolbar.tsx
|
|
2344
|
-
var
|
|
2345
|
-
var
|
|
2414
|
+
var React13 = __toESM(require("react"));
|
|
2415
|
+
var import_react_native13 = require("react-native");
|
|
2346
2416
|
var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
|
|
2347
2417
|
var import_lucide_react_native = require("lucide-react-native");
|
|
2348
2418
|
|
|
@@ -2361,7 +2431,7 @@ async function impact(style) {
|
|
|
2361
2431
|
}
|
|
2362
2432
|
|
|
2363
2433
|
// src/components/draw/DrawColorPicker.tsx
|
|
2364
|
-
var
|
|
2434
|
+
var import_react_native12 = require("react-native");
|
|
2365
2435
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2366
2436
|
function DrawColorPicker({
|
|
2367
2437
|
colors,
|
|
@@ -2396,10 +2466,10 @@ function DrawColorPicker({
|
|
|
2396
2466
|
return { ...base, ...selectedStyle, ...whiteStyle };
|
|
2397
2467
|
};
|
|
2398
2468
|
if (!expanded) {
|
|
2399
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2469
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.Pressable, { onPress: onToggle, style: [swatchStyle(selected, true), style] });
|
|
2400
2470
|
}
|
|
2401
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
2402
|
-
|
|
2471
|
+
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)(
|
|
2472
|
+
import_react_native12.Pressable,
|
|
2403
2473
|
{
|
|
2404
2474
|
onPress: () => {
|
|
2405
2475
|
onSelect(c);
|
|
@@ -2430,14 +2500,14 @@ function DrawToolbar({
|
|
|
2430
2500
|
style
|
|
2431
2501
|
}) {
|
|
2432
2502
|
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
|
-
|
|
2503
|
+
const { width: screenWidth, height: screenHeight } = (0, import_react_native13.useWindowDimensions)();
|
|
2504
|
+
const [expanded, setExpanded] = React13.useState(false);
|
|
2505
|
+
const pos = React13.useRef(new import_react_native13.Animated.ValueXY({ x: screenWidth / 2 - 110, y: -140 })).current;
|
|
2506
|
+
const start = React13.useRef({ x: 0, y: 0 });
|
|
2507
|
+
const currentPos = React13.useRef({ x: 0, y: 0 });
|
|
2508
|
+
React13.useEffect(() => {
|
|
2439
2509
|
if (hidden) return;
|
|
2440
|
-
|
|
2510
|
+
import_react_native13.Animated.spring(pos.y, {
|
|
2441
2511
|
toValue: insets.top + 60,
|
|
2442
2512
|
useNativeDriver: true,
|
|
2443
2513
|
damping: 12,
|
|
@@ -2445,7 +2515,7 @@ function DrawToolbar({
|
|
|
2445
2515
|
mass: 0.8
|
|
2446
2516
|
}).start();
|
|
2447
2517
|
}, [hidden, insets.top, pos.y]);
|
|
2448
|
-
|
|
2518
|
+
React13.useEffect(() => {
|
|
2449
2519
|
const id = pos.addListener((v) => {
|
|
2450
2520
|
currentPos.current = { x: v.x ?? 0, y: v.y ?? 0 };
|
|
2451
2521
|
});
|
|
@@ -2453,7 +2523,7 @@ function DrawToolbar({
|
|
|
2453
2523
|
pos.removeListener(id);
|
|
2454
2524
|
};
|
|
2455
2525
|
}, [pos]);
|
|
2456
|
-
const clamp2 =
|
|
2526
|
+
const clamp2 = React13.useCallback(
|
|
2457
2527
|
(x, y) => {
|
|
2458
2528
|
const minX = 10;
|
|
2459
2529
|
const maxX = Math.max(10, screenWidth - 230);
|
|
@@ -2463,8 +2533,8 @@ function DrawToolbar({
|
|
|
2463
2533
|
},
|
|
2464
2534
|
[insets.top, screenHeight, screenWidth]
|
|
2465
2535
|
);
|
|
2466
|
-
const panResponder =
|
|
2467
|
-
() =>
|
|
2536
|
+
const panResponder = React13.useMemo(
|
|
2537
|
+
() => import_react_native13.PanResponder.create({
|
|
2468
2538
|
onStartShouldSetPanResponder: () => false,
|
|
2469
2539
|
onMoveShouldSetPanResponder: (_e, g) => Math.abs(g.dx) > 5 || Math.abs(g.dy) > 5,
|
|
2470
2540
|
onPanResponderGrant: () => {
|
|
@@ -2476,7 +2546,7 @@ function DrawToolbar({
|
|
|
2476
2546
|
},
|
|
2477
2547
|
onPanResponderRelease: () => {
|
|
2478
2548
|
const next = clamp2(currentPos.current.x, currentPos.current.y);
|
|
2479
|
-
|
|
2549
|
+
import_react_native13.Animated.spring(pos, { toValue: next, useNativeDriver: true }).start();
|
|
2480
2550
|
}
|
|
2481
2551
|
}),
|
|
2482
2552
|
[clamp2, pos]
|
|
@@ -2491,9 +2561,9 @@ function DrawToolbar({
|
|
|
2491
2561
|
children
|
|
2492
2562
|
}) {
|
|
2493
2563
|
const isDisabled = Boolean(disabled) || Boolean(capturingDisabled);
|
|
2494
|
-
const [pressed, setPressed] =
|
|
2564
|
+
const [pressed, setPressed] = React13.useState(false);
|
|
2495
2565
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2496
|
-
|
|
2566
|
+
import_react_native13.View,
|
|
2497
2567
|
{
|
|
2498
2568
|
style: {
|
|
2499
2569
|
width: 28,
|
|
@@ -2505,7 +2575,7 @@ function DrawToolbar({
|
|
|
2505
2575
|
opacity: isDisabled ? 0.5 : pressed ? 0.85 : 1
|
|
2506
2576
|
},
|
|
2507
2577
|
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2508
|
-
|
|
2578
|
+
import_react_native13.Pressable,
|
|
2509
2579
|
{
|
|
2510
2580
|
accessibilityRole: "button",
|
|
2511
2581
|
accessibilityLabel,
|
|
@@ -2522,7 +2592,7 @@ function DrawToolbar({
|
|
|
2522
2592
|
);
|
|
2523
2593
|
}
|
|
2524
2594
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2525
|
-
|
|
2595
|
+
import_react_native13.Animated.View,
|
|
2526
2596
|
{
|
|
2527
2597
|
style: [
|
|
2528
2598
|
{
|
|
@@ -2539,7 +2609,7 @@ function DrawToolbar({
|
|
|
2539
2609
|
],
|
|
2540
2610
|
...panResponder.panHandlers,
|
|
2541
2611
|
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2542
|
-
|
|
2612
|
+
import_react_native13.View,
|
|
2543
2613
|
{
|
|
2544
2614
|
style: {
|
|
2545
2615
|
backgroundColor: "#F43F5E",
|
|
@@ -2547,7 +2617,7 @@ function DrawToolbar({
|
|
|
2547
2617
|
padding: 12,
|
|
2548
2618
|
minWidth: 220
|
|
2549
2619
|
},
|
|
2550
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2620
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native13.View, { style: { flexDirection: "row", alignItems: "center", gap: 8 }, children: [
|
|
2551
2621
|
renderDragHandle ? renderDragHandle() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react_native.GripVertical, { size: 20, color: "rgba(255, 255, 255, 0.6)" }),
|
|
2552
2622
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2553
2623
|
DrawColorPicker,
|
|
@@ -2565,7 +2635,7 @@ function DrawToolbar({
|
|
|
2565
2635
|
}
|
|
2566
2636
|
}
|
|
2567
2637
|
),
|
|
2568
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2638
|
+
/* @__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
2639
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2570
2640
|
CircleActionButton,
|
|
2571
2641
|
{
|
|
@@ -2603,7 +2673,7 @@ function DrawToolbar({
|
|
|
2603
2673
|
void impact("medium");
|
|
2604
2674
|
onDone();
|
|
2605
2675
|
},
|
|
2606
|
-
children: capturing ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2676
|
+
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
2677
|
}
|
|
2608
2678
|
)
|
|
2609
2679
|
] })
|
|
@@ -2629,7 +2699,7 @@ function DrawModeOverlay({
|
|
|
2629
2699
|
renderDragHandle
|
|
2630
2700
|
}) {
|
|
2631
2701
|
const theme = useTheme();
|
|
2632
|
-
const defaultPalette =
|
|
2702
|
+
const defaultPalette = React14.useMemo(
|
|
2633
2703
|
() => [
|
|
2634
2704
|
"#EF4444",
|
|
2635
2705
|
// Red
|
|
@@ -2647,11 +2717,11 @@ function DrawModeOverlay({
|
|
|
2647
2717
|
[]
|
|
2648
2718
|
);
|
|
2649
2719
|
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
|
-
|
|
2720
|
+
const [selectedColor, setSelectedColor] = React14.useState(colors[0] ?? "#EF4444");
|
|
2721
|
+
const [strokes, setStrokes] = React14.useState([]);
|
|
2722
|
+
const [capturing, setCapturing] = React14.useState(false);
|
|
2723
|
+
const [hideUi, setHideUi] = React14.useState(false);
|
|
2724
|
+
React14.useEffect(() => {
|
|
2655
2725
|
if (!visible) return;
|
|
2656
2726
|
setStrokes([]);
|
|
2657
2727
|
setSelectedColor(colors[0] ?? "#EF4444");
|
|
@@ -2659,14 +2729,14 @@ function DrawModeOverlay({
|
|
|
2659
2729
|
setHideUi(false);
|
|
2660
2730
|
}, [colors, visible]);
|
|
2661
2731
|
const canUndo = strokes.length > 0;
|
|
2662
|
-
const handleUndo =
|
|
2732
|
+
const handleUndo = React14.useCallback(() => {
|
|
2663
2733
|
setStrokes((prev) => prev.slice(0, -1));
|
|
2664
2734
|
}, []);
|
|
2665
|
-
const handleCancel =
|
|
2735
|
+
const handleCancel = React14.useCallback(() => {
|
|
2666
2736
|
setStrokes([]);
|
|
2667
2737
|
onCancel();
|
|
2668
2738
|
}, [onCancel]);
|
|
2669
|
-
const handleDone =
|
|
2739
|
+
const handleDone = React14.useCallback(async () => {
|
|
2670
2740
|
if (!captureTargetRef.current || capturing) return;
|
|
2671
2741
|
try {
|
|
2672
2742
|
setCapturing(true);
|
|
@@ -2688,7 +2758,7 @@ function DrawModeOverlay({
|
|
|
2688
2758
|
}
|
|
2689
2759
|
}, [captureTargetRef, capturing, onCapture]);
|
|
2690
2760
|
if (!visible) return null;
|
|
2691
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
2761
|
+
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
2762
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(EdgeGlowFrame, { visible: !hideUi, role: "danger", thickness: 50, intensity: 1 }),
|
|
2693
2763
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
2694
2764
|
DrawSurface,
|
|
@@ -2719,32 +2789,32 @@ function DrawModeOverlay({
|
|
|
2719
2789
|
)
|
|
2720
2790
|
] });
|
|
2721
2791
|
}
|
|
2722
|
-
var styles3 =
|
|
2792
|
+
var styles3 = import_react_native14.StyleSheet.create({
|
|
2723
2793
|
root: {
|
|
2724
2794
|
zIndex: 9999
|
|
2725
2795
|
}
|
|
2726
2796
|
});
|
|
2727
2797
|
|
|
2728
2798
|
// src/components/comments/AppCommentsSheet.tsx
|
|
2729
|
-
var
|
|
2730
|
-
var
|
|
2799
|
+
var React21 = __toESM(require("react"));
|
|
2800
|
+
var import_react_native20 = require("react-native");
|
|
2731
2801
|
var import_bottom_sheet3 = require("@gorhom/bottom-sheet");
|
|
2732
2802
|
var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
|
|
2733
2803
|
var import_liquid_glass4 = require("@callstack/liquid-glass");
|
|
2734
2804
|
var import_lucide_react_native4 = require("lucide-react-native");
|
|
2735
2805
|
|
|
2736
2806
|
// src/components/chat/ChatComposer.tsx
|
|
2737
|
-
var
|
|
2738
|
-
var
|
|
2807
|
+
var React16 = __toESM(require("react"));
|
|
2808
|
+
var import_react_native16 = require("react-native");
|
|
2739
2809
|
var import_liquid_glass3 = require("@callstack/liquid-glass");
|
|
2740
2810
|
var import_lucide_react_native3 = require("lucide-react-native");
|
|
2741
2811
|
|
|
2742
2812
|
// src/components/chat/MultilineTextInput.tsx
|
|
2743
|
-
var
|
|
2744
|
-
var
|
|
2813
|
+
var React15 = __toESM(require("react"));
|
|
2814
|
+
var import_react_native15 = require("react-native");
|
|
2745
2815
|
var import_bottom_sheet2 = require("@gorhom/bottom-sheet");
|
|
2746
2816
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2747
|
-
var MultilineTextInput =
|
|
2817
|
+
var MultilineTextInput = React15.forwardRef(function MultilineTextInput2({ useBottomSheetTextInput = false, placeholder, placeholderTextColor, style, ...props }, ref) {
|
|
2748
2818
|
const theme = useTheme();
|
|
2749
2819
|
const baseStyle = {
|
|
2750
2820
|
minHeight: 44,
|
|
@@ -2764,7 +2834,7 @@ var MultilineTextInput = React14.forwardRef(function MultilineTextInput2({ useBo
|
|
|
2764
2834
|
style: [baseStyle, style],
|
|
2765
2835
|
textAlignVertical: "top"
|
|
2766
2836
|
};
|
|
2767
|
-
return useBottomSheetTextInput ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_bottom_sheet2.BottomSheetTextInput, { ref, ...commonProps }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2837
|
+
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
2838
|
});
|
|
2769
2839
|
|
|
2770
2840
|
// src/components/icons/StudioIcons.tsx
|
|
@@ -2816,10 +2886,10 @@ function AspectRatioThumbnail({
|
|
|
2816
2886
|
onRemove,
|
|
2817
2887
|
renderRemoveIcon
|
|
2818
2888
|
}) {
|
|
2819
|
-
const [aspectRatio, setAspectRatio] =
|
|
2820
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2821
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2822
|
-
|
|
2889
|
+
const [aspectRatio, setAspectRatio] = React16.useState(1);
|
|
2890
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: { height: THUMBNAIL_HEIGHT, aspectRatio, position: "relative" }, children: [
|
|
2891
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.View, { style: { flex: 1, borderRadius: 8, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2892
|
+
import_react_native16.Image,
|
|
2823
2893
|
{
|
|
2824
2894
|
source: { uri },
|
|
2825
2895
|
style: { width: "100%", height: "100%" },
|
|
@@ -2832,7 +2902,7 @@ function AspectRatioThumbnail({
|
|
|
2832
2902
|
}
|
|
2833
2903
|
) }),
|
|
2834
2904
|
onRemove ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2835
|
-
|
|
2905
|
+
import_react_native16.Pressable,
|
|
2836
2906
|
{
|
|
2837
2907
|
style: {
|
|
2838
2908
|
position: "absolute",
|
|
@@ -2858,6 +2928,7 @@ function ChatComposer({
|
|
|
2858
2928
|
onChangeValue,
|
|
2859
2929
|
placeholder = "Describe the idea you want to build",
|
|
2860
2930
|
disabled = false,
|
|
2931
|
+
sendDisabled = false,
|
|
2861
2932
|
sending = false,
|
|
2862
2933
|
autoFocus = false,
|
|
2863
2934
|
onSend,
|
|
@@ -2872,19 +2943,19 @@ function ChatComposer({
|
|
|
2872
2943
|
style
|
|
2873
2944
|
}) {
|
|
2874
2945
|
const theme = useTheme();
|
|
2875
|
-
const [internal, setInternal] =
|
|
2946
|
+
const [internal, setInternal] = React16.useState("");
|
|
2876
2947
|
const text = value ?? internal;
|
|
2877
2948
|
const setText = onChangeValue ?? setInternal;
|
|
2878
2949
|
const hasAttachments = attachments.length > 0;
|
|
2879
2950
|
const hasText = text.trim().length > 0;
|
|
2880
2951
|
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
|
-
|
|
2952
|
+
const isButtonDisabled = sending || disabled || sendDisabled;
|
|
2953
|
+
const maxInputHeight = React16.useMemo(() => import_react_native16.Dimensions.get("window").height * 0.5, []);
|
|
2954
|
+
const shakeAnim = React16.useRef(new import_react_native16.Animated.Value(0)).current;
|
|
2955
|
+
const [sendPressed, setSendPressed] = React16.useState(false);
|
|
2956
|
+
const inputRef = React16.useRef(null);
|
|
2957
|
+
const prevAutoFocusRef = React16.useRef(false);
|
|
2958
|
+
React16.useEffect(() => {
|
|
2888
2959
|
const shouldFocus = autoFocus && !prevAutoFocusRef.current && !disabled && !sending;
|
|
2889
2960
|
prevAutoFocusRef.current = autoFocus;
|
|
2890
2961
|
if (!shouldFocus) return;
|
|
@@ -2894,17 +2965,17 @@ function ChatComposer({
|
|
|
2894
2965
|
}, 75);
|
|
2895
2966
|
return () => clearTimeout(t);
|
|
2896
2967
|
}, [autoFocus, disabled, sending]);
|
|
2897
|
-
const triggerShake =
|
|
2968
|
+
const triggerShake = React16.useCallback(() => {
|
|
2898
2969
|
shakeAnim.setValue(0);
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2970
|
+
import_react_native16.Animated.sequence([
|
|
2971
|
+
import_react_native16.Animated.timing(shakeAnim, { toValue: 10, duration: 50, useNativeDriver: true }),
|
|
2972
|
+
import_react_native16.Animated.timing(shakeAnim, { toValue: -10, duration: 50, useNativeDriver: true }),
|
|
2973
|
+
import_react_native16.Animated.timing(shakeAnim, { toValue: 10, duration: 50, useNativeDriver: true }),
|
|
2974
|
+
import_react_native16.Animated.timing(shakeAnim, { toValue: -10, duration: 50, useNativeDriver: true }),
|
|
2975
|
+
import_react_native16.Animated.timing(shakeAnim, { toValue: 0, duration: 50, useNativeDriver: true })
|
|
2905
2976
|
]).start();
|
|
2906
2977
|
}, [shakeAnim]);
|
|
2907
|
-
const handleSend =
|
|
2978
|
+
const handleSend = React16.useCallback(async () => {
|
|
2908
2979
|
if (isButtonDisabled) return;
|
|
2909
2980
|
if (!hasText) {
|
|
2910
2981
|
triggerShake();
|
|
@@ -2917,12 +2988,12 @@ function ChatComposer({
|
|
|
2917
2988
|
const textareaBgColor = theme.scheme === "dark" ? "#18181B" : "#F6F6F6";
|
|
2918
2989
|
const placeholderTextColor = theme.scheme === "dark" ? "#A1A1AA" : "#71717A";
|
|
2919
2990
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2920
|
-
|
|
2991
|
+
import_react_native16.View,
|
|
2921
2992
|
{
|
|
2922
2993
|
style: [{ paddingHorizontal: 16, paddingBottom: 12, paddingTop: 8 }, style],
|
|
2923
2994
|
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)(
|
|
2995
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: { flexDirection: "row", alignItems: "flex-end", gap: 8 }, children: [
|
|
2996
|
+
/* @__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
2997
|
import_liquid_glass3.LiquidGlassView,
|
|
2927
2998
|
{
|
|
2928
2999
|
style: [
|
|
@@ -2935,7 +3006,7 @@ function ChatComposer({
|
|
|
2935
3006
|
effect: "clear",
|
|
2936
3007
|
children: [
|
|
2937
3008
|
hasAttachments ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
2938
|
-
|
|
3009
|
+
import_react_native16.ScrollView,
|
|
2939
3010
|
{
|
|
2940
3011
|
horizontal: true,
|
|
2941
3012
|
showsHorizontalScrollIndicator: false,
|
|
@@ -2952,7 +3023,7 @@ function ChatComposer({
|
|
|
2952
3023
|
`attachment-${index}`
|
|
2953
3024
|
)),
|
|
2954
3025
|
onAddAttachment ? renderAddAttachment ? renderAddAttachment() : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2955
|
-
|
|
3026
|
+
import_react_native16.Pressable,
|
|
2956
3027
|
{
|
|
2957
3028
|
style: {
|
|
2958
3029
|
height: THUMBNAIL_HEIGHT,
|
|
@@ -3004,7 +3075,7 @@ function ChatComposer({
|
|
|
3004
3075
|
interactive: true,
|
|
3005
3076
|
effect: "clear",
|
|
3006
3077
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3007
|
-
|
|
3078
|
+
import_react_native16.View,
|
|
3008
3079
|
{
|
|
3009
3080
|
style: {
|
|
3010
3081
|
width: 44,
|
|
@@ -3015,7 +3086,7 @@ function ChatComposer({
|
|
|
3015
3086
|
opacity: isButtonDisabled ? 0.6 : sendPressed ? 0.9 : 1
|
|
3016
3087
|
},
|
|
3017
3088
|
children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3018
|
-
|
|
3089
|
+
import_react_native16.Pressable,
|
|
3019
3090
|
{
|
|
3020
3091
|
accessibilityRole: "button",
|
|
3021
3092
|
accessibilityLabel: "Send",
|
|
@@ -3024,7 +3095,7 @@ function ChatComposer({
|
|
|
3024
3095
|
onPressIn: () => setSendPressed(true),
|
|
3025
3096
|
onPressOut: () => setSendPressed(false),
|
|
3026
3097
|
style: { flex: 1, alignItems: "center", justifyContent: "center" },
|
|
3027
|
-
children: sending ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3098
|
+
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
3099
|
}
|
|
3029
3100
|
)
|
|
3030
3101
|
}
|
|
@@ -3037,11 +3108,11 @@ function ChatComposer({
|
|
|
3037
3108
|
}
|
|
3038
3109
|
|
|
3039
3110
|
// src/components/comments/CommentRow.tsx
|
|
3040
|
-
var
|
|
3041
|
-
var
|
|
3111
|
+
var React17 = __toESM(require("react"));
|
|
3112
|
+
var import_react_native18 = require("react-native");
|
|
3042
3113
|
|
|
3043
3114
|
// src/components/primitives/Avatar.tsx
|
|
3044
|
-
var
|
|
3115
|
+
var import_react_native17 = require("react-native");
|
|
3045
3116
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
3046
3117
|
function initialsFrom(name) {
|
|
3047
3118
|
var _a, _b;
|
|
@@ -3061,7 +3132,7 @@ function Avatar({
|
|
|
3061
3132
|
const radius = size / 2;
|
|
3062
3133
|
const fallbackBg = fallbackBackgroundColor ?? theme.colors.neutral;
|
|
3063
3134
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3064
|
-
|
|
3135
|
+
import_react_native17.View,
|
|
3065
3136
|
{
|
|
3066
3137
|
style: [
|
|
3067
3138
|
{
|
|
@@ -3076,7 +3147,7 @@ function Avatar({
|
|
|
3076
3147
|
style
|
|
3077
3148
|
],
|
|
3078
3149
|
children: uri ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
3079
|
-
|
|
3150
|
+
import_react_native17.Image,
|
|
3080
3151
|
{
|
|
3081
3152
|
source: { uri },
|
|
3082
3153
|
style: [{ width: size, height: size }, imageStyle],
|
|
@@ -3109,9 +3180,9 @@ function formatTimeAgo(iso) {
|
|
|
3109
3180
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
3110
3181
|
function CommentRow({ comment, showDivider }) {
|
|
3111
3182
|
const theme = useTheme();
|
|
3112
|
-
const [authorName, setAuthorName] =
|
|
3113
|
-
const [authorAvatar, setAuthorAvatar] =
|
|
3114
|
-
|
|
3183
|
+
const [authorName, setAuthorName] = React17.useState(null);
|
|
3184
|
+
const [authorAvatar, setAuthorAvatar] = React17.useState(null);
|
|
3185
|
+
React17.useEffect(() => {
|
|
3115
3186
|
let cancelled = false;
|
|
3116
3187
|
(async () => {
|
|
3117
3188
|
try {
|
|
@@ -3127,7 +3198,7 @@ function CommentRow({ comment, showDivider }) {
|
|
|
3127
3198
|
};
|
|
3128
3199
|
}, [comment.authorId]);
|
|
3129
3200
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
3130
|
-
|
|
3201
|
+
import_react_native18.View,
|
|
3131
3202
|
{
|
|
3132
3203
|
style: {
|
|
3133
3204
|
flexDirection: "row",
|
|
@@ -3138,8 +3209,8 @@ function CommentRow({ comment, showDivider }) {
|
|
|
3138
3209
|
},
|
|
3139
3210
|
children: [
|
|
3140
3211
|
/* @__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)(
|
|
3212
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native18.View, { style: { flex: 1, minWidth: 0, gap: 4 }, children: [
|
|
3213
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native18.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.sm }, children: [
|
|
3143
3214
|
/* @__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
3215
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, children: formatTimeAgo(comment.createdAt) })
|
|
3145
3216
|
] }),
|
|
@@ -3151,7 +3222,7 @@ function CommentRow({ comment, showDivider }) {
|
|
|
3151
3222
|
}
|
|
3152
3223
|
|
|
3153
3224
|
// src/components/comments/useAppComments.ts
|
|
3154
|
-
var
|
|
3225
|
+
var React18 = __toESM(require("react"));
|
|
3155
3226
|
|
|
3156
3227
|
// src/data/comments/remote.ts
|
|
3157
3228
|
var AppCommentsRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -3223,18 +3294,18 @@ var appCommentsRepository = new AppCommentsRepositoryImpl(appCommentsRemoteDataS
|
|
|
3223
3294
|
|
|
3224
3295
|
// src/components/comments/useAppComments.ts
|
|
3225
3296
|
function useAppComments(appId) {
|
|
3226
|
-
const [comments, setComments] =
|
|
3227
|
-
const [loading, setLoading] =
|
|
3228
|
-
const [sending, setSending] =
|
|
3229
|
-
const [error, setError] =
|
|
3230
|
-
const sortByCreatedAtAsc =
|
|
3297
|
+
const [comments, setComments] = React18.useState([]);
|
|
3298
|
+
const [loading, setLoading] = React18.useState(false);
|
|
3299
|
+
const [sending, setSending] = React18.useState(false);
|
|
3300
|
+
const [error, setError] = React18.useState(null);
|
|
3301
|
+
const sortByCreatedAtAsc = React18.useCallback((items) => {
|
|
3231
3302
|
return [...items].sort((a, b) => {
|
|
3232
3303
|
const at = a.createdAt ? new Date(a.createdAt).getTime() : 0;
|
|
3233
3304
|
const bt = b.createdAt ? new Date(b.createdAt).getTime() : 0;
|
|
3234
3305
|
return at - bt;
|
|
3235
3306
|
});
|
|
3236
3307
|
}, []);
|
|
3237
|
-
const refresh =
|
|
3308
|
+
const refresh = React18.useCallback(async () => {
|
|
3238
3309
|
if (!appId) {
|
|
3239
3310
|
setComments([]);
|
|
3240
3311
|
return;
|
|
@@ -3251,10 +3322,10 @@ function useAppComments(appId) {
|
|
|
3251
3322
|
setLoading(false);
|
|
3252
3323
|
}
|
|
3253
3324
|
}, [appId, sortByCreatedAtAsc]);
|
|
3254
|
-
|
|
3325
|
+
React18.useEffect(() => {
|
|
3255
3326
|
void refresh();
|
|
3256
3327
|
}, [refresh]);
|
|
3257
|
-
const create =
|
|
3328
|
+
const create = React18.useCallback(
|
|
3258
3329
|
async (text) => {
|
|
3259
3330
|
if (!appId) return;
|
|
3260
3331
|
const trimmed = text.trim();
|
|
@@ -3277,11 +3348,11 @@ function useAppComments(appId) {
|
|
|
3277
3348
|
}
|
|
3278
3349
|
|
|
3279
3350
|
// src/components/comments/useAppDetails.ts
|
|
3280
|
-
var
|
|
3351
|
+
var React19 = __toESM(require("react"));
|
|
3281
3352
|
function useAppDetails(appId) {
|
|
3282
|
-
const [app, setApp] =
|
|
3283
|
-
const [loading, setLoading] =
|
|
3284
|
-
|
|
3353
|
+
const [app, setApp] = React19.useState(null);
|
|
3354
|
+
const [loading, setLoading] = React19.useState(false);
|
|
3355
|
+
React19.useEffect(() => {
|
|
3285
3356
|
if (!appId) {
|
|
3286
3357
|
setApp(null);
|
|
3287
3358
|
return;
|
|
@@ -3306,25 +3377,30 @@ function useAppDetails(appId) {
|
|
|
3306
3377
|
}
|
|
3307
3378
|
|
|
3308
3379
|
// 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 =
|
|
3380
|
+
var React20 = __toESM(require("react"));
|
|
3381
|
+
var import_react_native19 = require("react-native");
|
|
3382
|
+
function useIosKeyboardSnapFix(sheetRef, options) {
|
|
3383
|
+
const [keyboardVisible, setKeyboardVisible] = React20.useState(false);
|
|
3384
|
+
React20.useEffect(() => {
|
|
3385
|
+
if (import_react_native19.Platform.OS !== "ios") return;
|
|
3386
|
+
const show = import_react_native19.Keyboard.addListener("keyboardWillShow", () => setKeyboardVisible(true));
|
|
3387
|
+
const hide = import_react_native19.Keyboard.addListener("keyboardWillHide", () => {
|
|
3388
|
+
var _a;
|
|
3317
3389
|
setKeyboardVisible(false);
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3390
|
+
const target = (options == null ? void 0 : options.targetIndex) ?? 1;
|
|
3391
|
+
const current = ((_a = options == null ? void 0 : options.getCurrentIndex) == null ? void 0 : _a.call(options)) ?? null;
|
|
3392
|
+
if (current === target) {
|
|
3393
|
+
setTimeout(() => {
|
|
3394
|
+
var _a2, _b;
|
|
3395
|
+
return (_b = (_a2 = sheetRef.current) == null ? void 0 : _a2.snapToIndex) == null ? void 0 : _b.call(_a2, target);
|
|
3396
|
+
}, 10);
|
|
3397
|
+
}
|
|
3322
3398
|
});
|
|
3323
3399
|
return () => {
|
|
3324
3400
|
show.remove();
|
|
3325
3401
|
hide.remove();
|
|
3326
3402
|
};
|
|
3327
|
-
}, [sheetRef]);
|
|
3403
|
+
}, [options == null ? void 0 : options.getCurrentIndex, options == null ? void 0 : options.targetIndex, sheetRef]);
|
|
3328
3404
|
return { keyboardVisible };
|
|
3329
3405
|
}
|
|
3330
3406
|
|
|
@@ -3333,12 +3409,16 @@ var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
|
3333
3409
|
function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
3334
3410
|
const theme = useTheme();
|
|
3335
3411
|
const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
|
|
3336
|
-
const sheetRef =
|
|
3337
|
-
const snapPoints =
|
|
3412
|
+
const sheetRef = React21.useRef(null);
|
|
3413
|
+
const snapPoints = React21.useMemo(() => ["50%", "90%"], []);
|
|
3414
|
+
const currentIndexRef = React21.useRef(1);
|
|
3338
3415
|
const { comments, loading, sending, error, create, refresh } = useAppComments(appId);
|
|
3339
3416
|
const { app, loading: loadingApp } = useAppDetails(appId);
|
|
3340
|
-
const { keyboardVisible } = useIosKeyboardSnapFix(sheetRef
|
|
3341
|
-
|
|
3417
|
+
const { keyboardVisible } = useIosKeyboardSnapFix(sheetRef, {
|
|
3418
|
+
getCurrentIndex: () => currentIndexRef.current,
|
|
3419
|
+
targetIndex: 1
|
|
3420
|
+
});
|
|
3421
|
+
React21.useEffect(() => {
|
|
3342
3422
|
var _a, _b;
|
|
3343
3423
|
if (appId) {
|
|
3344
3424
|
(_a = sheetRef.current) == null ? void 0 : _a.present();
|
|
@@ -3347,21 +3427,22 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3347
3427
|
(_b = sheetRef.current) == null ? void 0 : _b.dismiss();
|
|
3348
3428
|
}
|
|
3349
3429
|
}, [appId, refresh]);
|
|
3350
|
-
|
|
3430
|
+
React21.useEffect(() => {
|
|
3351
3431
|
if (!appId) return;
|
|
3352
3432
|
onCountChange == null ? void 0 : onCountChange(comments.length);
|
|
3353
3433
|
}, [appId, comments.length, onCountChange]);
|
|
3354
|
-
const renderBackdrop =
|
|
3434
|
+
const renderBackdrop = React21.useCallback(
|
|
3355
3435
|
(props) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_bottom_sheet3.BottomSheetBackdrop, { ...props, disappearsOnIndex: -1, appearsOnIndex: 0, opacity: 0.5 }),
|
|
3356
3436
|
[]
|
|
3357
3437
|
);
|
|
3358
|
-
const handleChange =
|
|
3438
|
+
const handleChange = React21.useCallback(
|
|
3359
3439
|
(index) => {
|
|
3440
|
+
currentIndexRef.current = index;
|
|
3360
3441
|
if (index === -1) onClose();
|
|
3361
3442
|
},
|
|
3362
3443
|
[onClose]
|
|
3363
3444
|
);
|
|
3364
|
-
const handlePlay =
|
|
3445
|
+
const handlePlay = React21.useCallback(async () => {
|
|
3365
3446
|
var _a;
|
|
3366
3447
|
if (!appId) return;
|
|
3367
3448
|
(_a = sheetRef.current) == null ? void 0 : _a.dismiss();
|
|
@@ -3379,17 +3460,17 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3379
3460
|
onChange: handleChange,
|
|
3380
3461
|
backgroundStyle: {
|
|
3381
3462
|
backgroundColor: theme.scheme === "dark" ? "#0B080F" : "#FFFFFF",
|
|
3382
|
-
borderTopLeftRadius:
|
|
3383
|
-
borderTopRightRadius:
|
|
3463
|
+
borderTopLeftRadius: import_react_native20.Platform.OS === "ios" ? 39 : 16,
|
|
3464
|
+
borderTopRightRadius: import_react_native20.Platform.OS === "ios" ? 39 : 16
|
|
3384
3465
|
},
|
|
3385
3466
|
handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
|
|
3386
3467
|
keyboardBehavior: "interactive",
|
|
3387
3468
|
keyboardBlurBehavior: "restore",
|
|
3388
3469
|
android_keyboardInputMode: "adjustResize",
|
|
3389
3470
|
topInset: insets.top,
|
|
3390
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3471
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native20.View, { style: { flex: 1 }, children: [
|
|
3391
3472
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
3392
|
-
|
|
3473
|
+
import_react_native20.View,
|
|
3393
3474
|
{
|
|
3394
3475
|
style: {
|
|
3395
3476
|
flexDirection: "row",
|
|
@@ -3425,7 +3506,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3425
3506
|
interactive: true,
|
|
3426
3507
|
effect: "clear",
|
|
3427
3508
|
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3428
|
-
|
|
3509
|
+
import_react_native20.View,
|
|
3429
3510
|
{
|
|
3430
3511
|
style: {
|
|
3431
3512
|
width: 32,
|
|
@@ -3437,7 +3518,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3437
3518
|
opacity: appId ? 1 : 0.5
|
|
3438
3519
|
},
|
|
3439
3520
|
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3440
|
-
|
|
3521
|
+
import_react_native20.Pressable,
|
|
3441
3522
|
{
|
|
3442
3523
|
disabled: !appId,
|
|
3443
3524
|
onPress: () => void handlePlay(),
|
|
@@ -3472,13 +3553,13 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3472
3553
|
},
|
|
3473
3554
|
keyboardShouldPersistTaps: "handled",
|
|
3474
3555
|
children: [
|
|
3475
|
-
loading && comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3556
|
+
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
3557
|
error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { variant: "captionMuted", style: { marginTop: theme.spacing.lg }, children: "Failed to load comments." }) : null
|
|
3477
3558
|
]
|
|
3478
3559
|
}
|
|
3479
3560
|
),
|
|
3480
3561
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3481
|
-
|
|
3562
|
+
import_react_native20.View,
|
|
3482
3563
|
{
|
|
3483
3564
|
style: {
|
|
3484
3565
|
position: "absolute",
|
|
@@ -3487,7 +3568,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3487
3568
|
bottom: 0,
|
|
3488
3569
|
paddingHorizontal: theme.spacing.lg,
|
|
3489
3570
|
paddingTop: theme.spacing.sm,
|
|
3490
|
-
paddingBottom:
|
|
3571
|
+
paddingBottom: import_react_native20.Platform.OS === "ios" ? keyboardVisible ? theme.spacing.lg : insets.bottom : insets.bottom + 10,
|
|
3491
3572
|
borderTopWidth: 1,
|
|
3492
3573
|
borderTopColor: withAlpha(theme.colors.border, 0.1),
|
|
3493
3574
|
backgroundColor: withAlpha(theme.colors.background, 0.8)
|
|
@@ -3501,7 +3582,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3501
3582
|
useBottomSheetTextInput: true,
|
|
3502
3583
|
onSend: async (text) => {
|
|
3503
3584
|
await create(text);
|
|
3504
|
-
|
|
3585
|
+
import_react_native20.Keyboard.dismiss();
|
|
3505
3586
|
}
|
|
3506
3587
|
}
|
|
3507
3588
|
)
|
|
@@ -3513,16 +3594,16 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3513
3594
|
}
|
|
3514
3595
|
|
|
3515
3596
|
// src/studio/ui/PreviewPanel.tsx
|
|
3516
|
-
var
|
|
3597
|
+
var import_react_native41 = require("react-native");
|
|
3517
3598
|
|
|
3518
3599
|
// src/components/preview/PreviewPage.tsx
|
|
3519
|
-
var
|
|
3600
|
+
var import_react_native21 = require("react-native");
|
|
3520
3601
|
var import_bottom_sheet4 = require("@gorhom/bottom-sheet");
|
|
3521
3602
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3522
3603
|
function PreviewPage({ header, children, contentStyle }) {
|
|
3523
3604
|
const theme = useTheme();
|
|
3524
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
3525
|
-
header ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3605
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_native21.View, { style: { flex: 1 }, children: [
|
|
3606
|
+
header ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native21.View, { children: header }) : null,
|
|
3526
3607
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
3527
3608
|
import_bottom_sheet4.BottomSheetScrollView,
|
|
3528
3609
|
{
|
|
@@ -3542,15 +3623,15 @@ function PreviewPage({ header, children, contentStyle }) {
|
|
|
3542
3623
|
}
|
|
3543
3624
|
|
|
3544
3625
|
// src/studio/ui/preview-panel/PreviewPanelHeader.tsx
|
|
3545
|
-
var
|
|
3626
|
+
var import_react_native24 = require("react-native");
|
|
3546
3627
|
|
|
3547
3628
|
// src/components/studio-sheet/StudioSheetHeader.tsx
|
|
3548
|
-
var
|
|
3629
|
+
var import_react_native22 = require("react-native");
|
|
3549
3630
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3550
3631
|
function StudioSheetHeader({ left, center, right, style }) {
|
|
3551
3632
|
const theme = useTheme();
|
|
3552
3633
|
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
3553
|
-
|
|
3634
|
+
import_react_native22.View,
|
|
3554
3635
|
{
|
|
3555
3636
|
style: [
|
|
3556
3637
|
{
|
|
@@ -3563,17 +3644,17 @@ function StudioSheetHeader({ left, center, right, style }) {
|
|
|
3563
3644
|
style
|
|
3564
3645
|
],
|
|
3565
3646
|
children: [
|
|
3566
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3567
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3568
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3647
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.View, { style: { flexDirection: "row", alignItems: "center" }, children: left }),
|
|
3648
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.View, { style: { flex: 1, alignItems: "center" }, children: center }),
|
|
3649
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.View, { style: { flexDirection: "row", alignItems: "center" }, children: right })
|
|
3569
3650
|
]
|
|
3570
3651
|
}
|
|
3571
3652
|
);
|
|
3572
3653
|
}
|
|
3573
3654
|
|
|
3574
3655
|
// src/components/studio-sheet/StudioSheetHeaderIconButton.tsx
|
|
3575
|
-
var
|
|
3576
|
-
var
|
|
3656
|
+
var React22 = __toESM(require("react"));
|
|
3657
|
+
var import_react_native23 = require("react-native");
|
|
3577
3658
|
var import_liquid_glass5 = require("@callstack/liquid-glass");
|
|
3578
3659
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3579
3660
|
function StudioSheetHeaderIconButton({
|
|
@@ -3587,19 +3668,19 @@ function StudioSheetHeaderIconButton({
|
|
|
3587
3668
|
}) {
|
|
3588
3669
|
const theme = useTheme();
|
|
3589
3670
|
const size = 44;
|
|
3590
|
-
const [pressed, setPressed] =
|
|
3671
|
+
const [pressed, setPressed] = React22.useState(false);
|
|
3591
3672
|
const solidBg = intent === "danger" ? theme.colors.danger : intent === "primary" ? theme.colors.primary : theme.colors.neutral;
|
|
3592
3673
|
const glassFallbackBg = theme.scheme === "dark" ? "#18181B" : "#F6F6F6";
|
|
3593
3674
|
const glassInnerBg = intent === "danger" ? theme.colors.danger : theme.colors.primary;
|
|
3594
3675
|
const resolvedOpacity = disabled ? 0.6 : pressed ? 0.9 : 1;
|
|
3595
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native23.View, { style, children: appearance === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3596
3677
|
import_liquid_glass5.LiquidGlassView,
|
|
3597
3678
|
{
|
|
3598
3679
|
style: [{ borderRadius: 100 }, !import_liquid_glass5.isLiquidGlassSupported && { backgroundColor: glassFallbackBg }],
|
|
3599
3680
|
interactive: true,
|
|
3600
3681
|
effect: "clear",
|
|
3601
3682
|
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3602
|
-
|
|
3683
|
+
import_react_native23.View,
|
|
3603
3684
|
{
|
|
3604
3685
|
style: {
|
|
3605
3686
|
width: size,
|
|
@@ -3611,7 +3692,7 @@ function StudioSheetHeaderIconButton({
|
|
|
3611
3692
|
opacity: resolvedOpacity
|
|
3612
3693
|
},
|
|
3613
3694
|
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3614
|
-
|
|
3695
|
+
import_react_native23.Pressable,
|
|
3615
3696
|
{
|
|
3616
3697
|
accessibilityRole: "button",
|
|
3617
3698
|
accessibilityLabel,
|
|
@@ -3630,7 +3711,7 @@ function StudioSheetHeaderIconButton({
|
|
|
3630
3711
|
)
|
|
3631
3712
|
}
|
|
3632
3713
|
) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3633
|
-
|
|
3714
|
+
import_react_native23.View,
|
|
3634
3715
|
{
|
|
3635
3716
|
style: {
|
|
3636
3717
|
width: size,
|
|
@@ -3642,7 +3723,7 @@ function StudioSheetHeaderIconButton({
|
|
|
3642
3723
|
opacity: resolvedOpacity
|
|
3643
3724
|
},
|
|
3644
3725
|
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3645
|
-
|
|
3726
|
+
import_react_native23.Pressable,
|
|
3646
3727
|
{
|
|
3647
3728
|
accessibilityRole: "button",
|
|
3648
3729
|
accessibilityLabel,
|
|
@@ -3669,7 +3750,7 @@ function PreviewPanelHeader({ isOwner, onClose, onNavigateHome, onGoToChat }) {
|
|
|
3669
3750
|
{
|
|
3670
3751
|
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
3752
|
center: null,
|
|
3672
|
-
right: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
3753
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native24.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
3673
3754
|
isOwner ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3674
3755
|
StudioSheetHeaderIconButton,
|
|
3675
3756
|
{
|
|
@@ -3688,10 +3769,10 @@ function PreviewPanelHeader({ isOwner, onClose, onNavigateHome, onGoToChat }) {
|
|
|
3688
3769
|
}
|
|
3689
3770
|
|
|
3690
3771
|
// src/components/preview/PreviewHeroCard.tsx
|
|
3691
|
-
var
|
|
3772
|
+
var import_react_native26 = require("react-native");
|
|
3692
3773
|
|
|
3693
3774
|
// src/components/primitives/Surface.tsx
|
|
3694
|
-
var
|
|
3775
|
+
var import_react_native25 = require("react-native");
|
|
3695
3776
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3696
3777
|
function backgroundFor(variant, theme) {
|
|
3697
3778
|
const { colors } = theme;
|
|
@@ -3710,7 +3791,7 @@ function backgroundFor(variant, theme) {
|
|
|
3710
3791
|
function Surface({ variant = "surface", border = false, style, ...props }) {
|
|
3711
3792
|
const theme = useTheme();
|
|
3712
3793
|
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3713
|
-
|
|
3794
|
+
import_react_native25.View,
|
|
3714
3795
|
{
|
|
3715
3796
|
...props,
|
|
3716
3797
|
style: [
|
|
@@ -3766,32 +3847,32 @@ function PreviewHeroCard({
|
|
|
3766
3847
|
},
|
|
3767
3848
|
style
|
|
3768
3849
|
],
|
|
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)(
|
|
3850
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native26.View, { style: { flex: 1 }, children: [
|
|
3851
|
+
background ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native26.View, { style: { position: "absolute", inset: 0 }, children: background }) : null,
|
|
3852
|
+
image ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native26.View, { style: { position: "absolute", inset: 0 }, children: image }) : null,
|
|
3853
|
+
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,
|
|
3854
|
+
overlayBottom ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native26.View, { style: { flex: 1, justifyContent: "flex-end" }, children: overlayBottom }) : null
|
|
3774
3855
|
] })
|
|
3775
3856
|
}
|
|
3776
3857
|
);
|
|
3777
3858
|
}
|
|
3778
3859
|
|
|
3779
3860
|
// src/components/preview/PreviewPlaceholder.tsx
|
|
3780
|
-
var
|
|
3781
|
-
var
|
|
3861
|
+
var React23 = __toESM(require("react"));
|
|
3862
|
+
var import_react_native27 = require("react-native");
|
|
3782
3863
|
var import_expo_linear_gradient2 = require("expo-linear-gradient");
|
|
3783
3864
|
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
3784
3865
|
function PreviewPlaceholder({ visible, style }) {
|
|
3785
3866
|
if (!visible) return null;
|
|
3786
|
-
const opacityAnim =
|
|
3787
|
-
|
|
3867
|
+
const opacityAnim = React23.useRef(new import_react_native27.Animated.Value(0)).current;
|
|
3868
|
+
React23.useEffect(() => {
|
|
3788
3869
|
if (!visible) return;
|
|
3789
|
-
const animation =
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3870
|
+
const animation = import_react_native27.Animated.loop(
|
|
3871
|
+
import_react_native27.Animated.sequence([
|
|
3872
|
+
import_react_native27.Animated.timing(opacityAnim, { toValue: 1, duration: 1500, useNativeDriver: true }),
|
|
3873
|
+
import_react_native27.Animated.timing(opacityAnim, { toValue: 2, duration: 1500, useNativeDriver: true }),
|
|
3874
|
+
import_react_native27.Animated.timing(opacityAnim, { toValue: 3, duration: 1500, useNativeDriver: true }),
|
|
3875
|
+
import_react_native27.Animated.timing(opacityAnim, { toValue: 0, duration: 1500, useNativeDriver: true })
|
|
3795
3876
|
])
|
|
3796
3877
|
);
|
|
3797
3878
|
animation.start();
|
|
@@ -3802,7 +3883,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3802
3883
|
const opacity3 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 1, 0] });
|
|
3803
3884
|
const opacity4 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 0, 1] });
|
|
3804
3885
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
3805
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3886
|
+
/* @__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
3887
|
import_expo_linear_gradient2.LinearGradient,
|
|
3807
3888
|
{
|
|
3808
3889
|
colors: ["rgba(98, 0, 238, 0.45)", "rgba(168, 85, 247, 0.35)"],
|
|
@@ -3811,7 +3892,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3811
3892
|
style: { width: "100%", height: "100%" }
|
|
3812
3893
|
}
|
|
3813
3894
|
) }),
|
|
3814
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3895
|
+
/* @__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
3896
|
import_expo_linear_gradient2.LinearGradient,
|
|
3816
3897
|
{
|
|
3817
3898
|
colors: ["rgba(168, 85, 247, 0.45)", "rgba(139, 92, 246, 0.35)"],
|
|
@@ -3820,7 +3901,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3820
3901
|
style: { width: "100%", height: "100%" }
|
|
3821
3902
|
}
|
|
3822
3903
|
) }),
|
|
3823
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3904
|
+
/* @__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
3905
|
import_expo_linear_gradient2.LinearGradient,
|
|
3825
3906
|
{
|
|
3826
3907
|
colors: ["rgba(139, 92, 246, 0.45)", "rgba(126, 34, 206, 0.35)"],
|
|
@@ -3829,7 +3910,7 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3829
3910
|
style: { width: "100%", height: "100%" }
|
|
3830
3911
|
}
|
|
3831
3912
|
) }),
|
|
3832
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3913
|
+
/* @__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
3914
|
import_expo_linear_gradient2.LinearGradient,
|
|
3834
3915
|
{
|
|
3835
3916
|
colors: ["rgba(126, 34, 206, 0.45)", "rgba(98, 0, 238, 0.35)"],
|
|
@@ -3842,12 +3923,12 @@ function PreviewPlaceholder({ visible, style }) {
|
|
|
3842
3923
|
}
|
|
3843
3924
|
|
|
3844
3925
|
// src/components/preview/PreviewImage.tsx
|
|
3845
|
-
var
|
|
3926
|
+
var import_react_native28 = require("react-native");
|
|
3846
3927
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
3847
3928
|
function PreviewImage({ uri, onLoad, style }) {
|
|
3848
3929
|
if (!uri) return null;
|
|
3849
3930
|
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
|
|
3850
|
-
|
|
3931
|
+
import_react_native28.Image,
|
|
3851
3932
|
{
|
|
3852
3933
|
source: { uri },
|
|
3853
3934
|
resizeMode: "cover",
|
|
@@ -3858,7 +3939,7 @@ function PreviewImage({ uri, onLoad, style }) {
|
|
|
3858
3939
|
}
|
|
3859
3940
|
|
|
3860
3941
|
// src/components/preview/StatsBar.tsx
|
|
3861
|
-
var
|
|
3942
|
+
var import_react_native29 = require("react-native");
|
|
3862
3943
|
var import_liquid_glass6 = require("@callstack/liquid-glass");
|
|
3863
3944
|
var import_lucide_react_native5 = require("lucide-react-native");
|
|
3864
3945
|
|
|
@@ -3891,7 +3972,7 @@ function StatsBar({
|
|
|
3891
3972
|
const theme = useTheme();
|
|
3892
3973
|
const statsBgColor = theme.scheme === "dark" ? "rgba(24, 24, 27, 0.5)" : "rgba(255, 255, 255, 0.5)";
|
|
3893
3974
|
return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3894
|
-
|
|
3975
|
+
import_react_native29.View,
|
|
3895
3976
|
{
|
|
3896
3977
|
style: [
|
|
3897
3978
|
{ position: "absolute", bottom: 12, width: "100%", paddingHorizontal: 12 },
|
|
@@ -3907,15 +3988,15 @@ function StatsBar({
|
|
|
3907
3988
|
!import_liquid_glass6.isLiquidGlassSupported && { backgroundColor: statsBgColor }
|
|
3908
3989
|
],
|
|
3909
3990
|
effect: "clear",
|
|
3910
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
3991
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native29.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16 }, children: [
|
|
3911
3992
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3912
|
-
|
|
3993
|
+
import_react_native29.Pressable,
|
|
3913
3994
|
{
|
|
3914
3995
|
disabled: !onPressLike,
|
|
3915
3996
|
onPress: onPressLike,
|
|
3916
3997
|
hitSlop: 8,
|
|
3917
3998
|
style: { paddingVertical: 8 },
|
|
3918
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
3999
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native29.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
3919
4000
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3920
4001
|
import_lucide_react_native5.Heart,
|
|
3921
4002
|
{
|
|
@@ -3925,7 +4006,7 @@ function StatsBar({
|
|
|
3925
4006
|
fill: isLiked ? theme.colors.danger : "transparent"
|
|
3926
4007
|
}
|
|
3927
4008
|
),
|
|
3928
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
4009
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native29.View, { style: { width: 4 } }),
|
|
3929
4010
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3930
4011
|
Text,
|
|
3931
4012
|
{
|
|
@@ -3941,22 +4022,22 @@ function StatsBar({
|
|
|
3941
4022
|
}
|
|
3942
4023
|
),
|
|
3943
4024
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3944
|
-
|
|
4025
|
+
import_react_native29.Pressable,
|
|
3945
4026
|
{
|
|
3946
4027
|
disabled: !onPressComments,
|
|
3947
4028
|
onPress: onPressComments,
|
|
3948
4029
|
hitSlop: 8,
|
|
3949
4030
|
style: { paddingVertical: 8 },
|
|
3950
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
4031
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native29.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
3951
4032
|
/* @__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)(
|
|
4033
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native29.View, { style: { width: 4 } }),
|
|
3953
4034
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: commentCount })
|
|
3954
4035
|
] })
|
|
3955
4036
|
}
|
|
3956
4037
|
),
|
|
3957
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
3958
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
3959
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
4038
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native29.View, { style: { flexDirection: "row", alignItems: "center", paddingVertical: 8 }, children: [
|
|
4039
|
+
/* @__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" }) }),
|
|
4040
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native29.View, { style: { width: 4 } }),
|
|
3960
4041
|
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: forkCount })
|
|
3961
4042
|
] })
|
|
3962
4043
|
] })
|
|
@@ -3967,7 +4048,7 @@ function StatsBar({
|
|
|
3967
4048
|
}
|
|
3968
4049
|
|
|
3969
4050
|
// src/components/preview/PreviewStatusBadge.tsx
|
|
3970
|
-
var
|
|
4051
|
+
var import_react_native30 = require("react-native");
|
|
3971
4052
|
var import_lucide_react_native6 = require("lucide-react-native");
|
|
3972
4053
|
|
|
3973
4054
|
// src/data/apps/types.ts
|
|
@@ -4012,7 +4093,7 @@ function PreviewStatusBadge({ status }) {
|
|
|
4012
4093
|
const IconComp = STATUS_ICON[status];
|
|
4013
4094
|
const label = APP_STATUS_LABEL[status] ?? status;
|
|
4014
4095
|
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
4015
|
-
|
|
4096
|
+
import_react_native30.View,
|
|
4016
4097
|
{
|
|
4017
4098
|
style: {
|
|
4018
4099
|
flexDirection: "row",
|
|
@@ -4065,10 +4146,10 @@ function PreviewHeroSection({
|
|
|
4065
4146
|
}
|
|
4066
4147
|
|
|
4067
4148
|
// src/studio/ui/preview-panel/PreviewMetaSection.tsx
|
|
4068
|
-
var
|
|
4149
|
+
var import_react_native32 = require("react-native");
|
|
4069
4150
|
|
|
4070
4151
|
// src/components/preview/PreviewMetaRow.tsx
|
|
4071
|
-
var
|
|
4152
|
+
var import_react_native31 = require("react-native");
|
|
4072
4153
|
var import_jsx_runtime32 = require("react/jsx-runtime");
|
|
4073
4154
|
function PreviewMetaRow({
|
|
4074
4155
|
avatarUri,
|
|
@@ -4080,10 +4161,10 @@ function PreviewMetaRow({
|
|
|
4080
4161
|
style
|
|
4081
4162
|
}) {
|
|
4082
4163
|
const theme = useTheme();
|
|
4083
|
-
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
4084
|
-
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
|
|
4164
|
+
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react_native31.View, { style: [{ alignSelf: "stretch" }, style], children: [
|
|
4165
|
+
/* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react_native31.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
4085
4166
|
/* @__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)(
|
|
4167
|
+
/* @__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
4168
|
/* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4088
4169
|
Text,
|
|
4089
4170
|
{
|
|
@@ -4098,9 +4179,9 @@ function PreviewMetaRow({
|
|
|
4098
4179
|
children: title
|
|
4099
4180
|
}
|
|
4100
4181
|
),
|
|
4101
|
-
tag ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4182
|
+
tag ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_native31.View, { style: { marginLeft: theme.spacing.sm }, children: tag }) : null
|
|
4102
4183
|
] }),
|
|
4103
|
-
rightMetric ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4184
|
+
rightMetric ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_native31.View, { children: rightMetric }) : null
|
|
4104
4185
|
] }),
|
|
4105
4186
|
subtitle ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
|
|
4106
4187
|
Text,
|
|
@@ -4156,9 +4237,9 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
|
|
|
4156
4237
|
subtitle: app.description,
|
|
4157
4238
|
avatarUri: (creator == null ? void 0 : creator.avatar) ?? null,
|
|
4158
4239
|
creatorName: (creator == null ? void 0 : creator.name) ?? null,
|
|
4159
|
-
tag: isOwner || app.forkedFromAppId ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
4240
|
+
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
4241
|
rightMetric: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
4161
|
-
|
|
4242
|
+
import_react_native32.View,
|
|
4162
4243
|
{
|
|
4163
4244
|
style: {
|
|
4164
4245
|
flexDirection: "row",
|
|
@@ -4192,10 +4273,10 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
|
|
|
4192
4273
|
}
|
|
4193
4274
|
|
|
4194
4275
|
// src/studio/ui/preview-panel/PreviewCustomizeSection.tsx
|
|
4195
|
-
var
|
|
4276
|
+
var import_react_native34 = require("react-native");
|
|
4196
4277
|
|
|
4197
4278
|
// src/studio/ui/preview-panel/PressableCardRow.tsx
|
|
4198
|
-
var
|
|
4279
|
+
var import_react_native33 = require("react-native");
|
|
4199
4280
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
4200
4281
|
function PressableCardRow({
|
|
4201
4282
|
accessibilityLabel,
|
|
@@ -4208,20 +4289,20 @@ function PressableCardRow({
|
|
|
4208
4289
|
style
|
|
4209
4290
|
}) {
|
|
4210
4291
|
return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4211
|
-
|
|
4292
|
+
import_react_native33.Pressable,
|
|
4212
4293
|
{
|
|
4213
4294
|
accessibilityRole: "button",
|
|
4214
4295
|
accessibilityLabel,
|
|
4215
4296
|
disabled,
|
|
4216
4297
|
onPress,
|
|
4217
4298
|
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)(
|
|
4299
|
+
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
4300
|
left,
|
|
4220
|
-
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
4301
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native33.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4221
4302
|
title,
|
|
4222
4303
|
subtitle ? subtitle : null
|
|
4223
4304
|
] }),
|
|
4224
|
-
right ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
4305
|
+
right ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_native33.View, { style: { marginLeft: 16 }, children: right }) : null
|
|
4225
4306
|
] }) })
|
|
4226
4307
|
}
|
|
4227
4308
|
);
|
|
@@ -4263,7 +4344,7 @@ function PreviewCustomizeSection({
|
|
|
4263
4344
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
4264
4345
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SectionTitle, { children: "Customize" }),
|
|
4265
4346
|
showProcessing ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4266
|
-
|
|
4347
|
+
import_react_native34.View,
|
|
4267
4348
|
{
|
|
4268
4349
|
style: {
|
|
4269
4350
|
flexDirection: "row",
|
|
@@ -4277,7 +4358,7 @@ function PreviewCustomizeSection({
|
|
|
4277
4358
|
},
|
|
4278
4359
|
children: [
|
|
4279
4360
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4280
|
-
|
|
4361
|
+
import_react_native34.View,
|
|
4281
4362
|
{
|
|
4282
4363
|
style: {
|
|
4283
4364
|
width: 40,
|
|
@@ -4288,10 +4369,10 @@ function PreviewCustomizeSection({
|
|
|
4288
4369
|
backgroundColor: withAlpha(theme.colors.warning, 0.1),
|
|
4289
4370
|
marginRight: theme.spacing.lg
|
|
4290
4371
|
},
|
|
4291
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4372
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native34.ActivityIndicator, { color: theme.colors.warning, size: "small" })
|
|
4292
4373
|
}
|
|
4293
4374
|
),
|
|
4294
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
4375
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native34.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4295
4376
|
/* @__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
4377
|
/* @__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
4378
|
] })
|
|
@@ -4312,7 +4393,7 @@ function PreviewCustomizeSection({
|
|
|
4312
4393
|
marginBottom: theme.spacing.sm
|
|
4313
4394
|
},
|
|
4314
4395
|
left: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4315
|
-
|
|
4396
|
+
import_react_native34.View,
|
|
4316
4397
|
{
|
|
4317
4398
|
style: {
|
|
4318
4399
|
width: 40,
|
|
@@ -4345,7 +4426,7 @@ function PreviewCustomizeSection({
|
|
|
4345
4426
|
marginBottom: theme.spacing.sm
|
|
4346
4427
|
},
|
|
4347
4428
|
left: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
4348
|
-
|
|
4429
|
+
import_react_native34.View,
|
|
4349
4430
|
{
|
|
4350
4431
|
style: {
|
|
4351
4432
|
width: 40,
|
|
@@ -4368,17 +4449,17 @@ function PreviewCustomizeSection({
|
|
|
4368
4449
|
}
|
|
4369
4450
|
|
|
4370
4451
|
// src/studio/ui/preview-panel/PreviewCollaborateSection.tsx
|
|
4371
|
-
var
|
|
4372
|
-
var
|
|
4452
|
+
var React29 = __toESM(require("react"));
|
|
4453
|
+
var import_react_native40 = require("react-native");
|
|
4373
4454
|
var import_lucide_react_native9 = require("lucide-react-native");
|
|
4374
4455
|
|
|
4375
4456
|
// src/components/merge-requests/MergeRequestStatusCard.tsx
|
|
4376
|
-
var
|
|
4377
|
-
var
|
|
4457
|
+
var React25 = __toESM(require("react"));
|
|
4458
|
+
var import_react_native36 = require("react-native");
|
|
4378
4459
|
var import_lucide_react_native7 = require("lucide-react-native");
|
|
4379
4460
|
|
|
4380
4461
|
// src/components/primitives/MarkdownText.tsx
|
|
4381
|
-
var
|
|
4462
|
+
var import_react_native35 = require("react-native");
|
|
4382
4463
|
var import_react_native_markdown_display = __toESM(require("react-native-markdown-display"));
|
|
4383
4464
|
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
4384
4465
|
function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
@@ -4391,7 +4472,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
|
4391
4472
|
const codeTextColor = isDark ? "#FFFFFF" : theme.colors.text;
|
|
4392
4473
|
const paragraphBottom = variant === "mergeRequest" ? 8 : 6;
|
|
4393
4474
|
const baseLineHeight = variant === "mergeRequest" ? 22 : 20;
|
|
4394
|
-
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4475
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_react_native35.View, { style, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
4395
4476
|
import_react_native_markdown_display.default,
|
|
4396
4477
|
{
|
|
4397
4478
|
style: {
|
|
@@ -4404,7 +4485,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
|
|
|
4404
4485
|
paddingHorizontal: variant === "mergeRequest" ? 6 : 4,
|
|
4405
4486
|
paddingVertical: variant === "mergeRequest" ? 2 : 0,
|
|
4406
4487
|
borderRadius: variant === "mergeRequest" ? 6 : 4,
|
|
4407
|
-
fontFamily:
|
|
4488
|
+
fontFamily: import_react_native35.Platform.OS === "ios" ? "Menlo" : "monospace",
|
|
4408
4489
|
fontSize: 13
|
|
4409
4490
|
},
|
|
4410
4491
|
code_block: {
|
|
@@ -4455,11 +4536,11 @@ function toIsoString(input) {
|
|
|
4455
4536
|
}
|
|
4456
4537
|
|
|
4457
4538
|
// src/components/merge-requests/useControlledExpansion.ts
|
|
4458
|
-
var
|
|
4539
|
+
var React24 = __toESM(require("react"));
|
|
4459
4540
|
function useControlledExpansion(props) {
|
|
4460
|
-
const [uncontrolled, setUncontrolled] =
|
|
4541
|
+
const [uncontrolled, setUncontrolled] = React24.useState(false);
|
|
4461
4542
|
const expanded = props.expanded ?? uncontrolled;
|
|
4462
|
-
const setExpanded =
|
|
4543
|
+
const setExpanded = React24.useCallback(
|
|
4463
4544
|
(next) => {
|
|
4464
4545
|
var _a;
|
|
4465
4546
|
(_a = props.onExpandedChange) == null ? void 0 : _a.call(props, next);
|
|
@@ -4484,8 +4565,8 @@ function MergeRequestStatusCard({
|
|
|
4484
4565
|
const isDark = theme.scheme === "dark";
|
|
4485
4566
|
const textColor = isDark ? "#FFFFFF" : "#000000";
|
|
4486
4567
|
const subTextColor = isDark ? "#A1A1AA" : "#71717A";
|
|
4487
|
-
const status =
|
|
4488
|
-
const { StatusIcon, iconColor, bgColor, statusText } =
|
|
4568
|
+
const status = React25.useMemo(() => getMergeRequestStatusDisplay(String(mergeRequest.status)), [mergeRequest.status]);
|
|
4569
|
+
const { StatusIcon, iconColor, bgColor, statusText } = React25.useMemo(() => {
|
|
4489
4570
|
switch (mergeRequest.status) {
|
|
4490
4571
|
case "approved":
|
|
4491
4572
|
case "merged":
|
|
@@ -4516,15 +4597,15 @@ function MergeRequestStatusCard({
|
|
|
4516
4597
|
const createdIso = toIsoString(mergeRequest.createdAt ?? null);
|
|
4517
4598
|
const headerTimeAgo = updatedIso ? formatTimeAgo(updatedIso) : "";
|
|
4518
4599
|
const createdTimeAgo = createdIso ? formatTimeAgo(createdIso) : "";
|
|
4519
|
-
const rotate =
|
|
4520
|
-
|
|
4521
|
-
|
|
4600
|
+
const rotate = React25.useRef(new import_react_native36.Animated.Value(expanded ? 1 : 0)).current;
|
|
4601
|
+
React25.useEffect(() => {
|
|
4602
|
+
import_react_native36.Animated.timing(rotate, {
|
|
4522
4603
|
toValue: expanded ? 1 : 0,
|
|
4523
4604
|
duration: 200,
|
|
4524
4605
|
useNativeDriver: true
|
|
4525
4606
|
}).start();
|
|
4526
4607
|
}, [expanded, rotate]);
|
|
4527
|
-
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4608
|
+
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
4609
|
Card,
|
|
4529
4610
|
{
|
|
4530
4611
|
padded: false,
|
|
@@ -4537,10 +4618,10 @@ function MergeRequestStatusCard({
|
|
|
4537
4618
|
style
|
|
4538
4619
|
],
|
|
4539
4620
|
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)(
|
|
4621
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native36.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.lg }, children: [
|
|
4622
|
+
/* @__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 }) }),
|
|
4623
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native36.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4624
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native36.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
4544
4625
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4545
4626
|
Text,
|
|
4546
4627
|
{
|
|
@@ -4559,8 +4640,8 @@ function MergeRequestStatusCard({
|
|
|
4559
4640
|
] }),
|
|
4560
4641
|
/* @__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
4642
|
] }),
|
|
4562
|
-
headerRight ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4563
|
-
|
|
4643
|
+
headerRight ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native36.View, { children: headerRight }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4644
|
+
import_react_native36.Animated.View,
|
|
4564
4645
|
{
|
|
4565
4646
|
style: {
|
|
4566
4647
|
transform: [
|
|
@@ -4573,7 +4654,7 @@ function MergeRequestStatusCard({
|
|
|
4573
4654
|
}
|
|
4574
4655
|
)
|
|
4575
4656
|
] }),
|
|
4576
|
-
expanded ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
4657
|
+
expanded ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native36.View, { style: { marginTop: 16, marginLeft: 56 }, children: [
|
|
4577
4658
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
4578
4659
|
Text,
|
|
4579
4660
|
{
|
|
@@ -4608,17 +4689,17 @@ function MergeRequestStatusCard({
|
|
|
4608
4689
|
}
|
|
4609
4690
|
|
|
4610
4691
|
// src/components/merge-requests/ReviewMergeRequestCarousel.tsx
|
|
4611
|
-
var
|
|
4612
|
-
var
|
|
4692
|
+
var React28 = __toESM(require("react"));
|
|
4693
|
+
var import_react_native39 = require("react-native");
|
|
4613
4694
|
|
|
4614
4695
|
// src/components/merge-requests/ReviewMergeRequestCard.tsx
|
|
4615
|
-
var
|
|
4616
|
-
var
|
|
4696
|
+
var React27 = __toESM(require("react"));
|
|
4697
|
+
var import_react_native38 = require("react-native");
|
|
4617
4698
|
var import_lucide_react_native8 = require("lucide-react-native");
|
|
4618
4699
|
|
|
4619
4700
|
// src/components/merge-requests/ReviewMergeRequestActionButton.tsx
|
|
4620
|
-
var
|
|
4621
|
-
var
|
|
4701
|
+
var React26 = __toESM(require("react"));
|
|
4702
|
+
var import_react_native37 = require("react-native");
|
|
4622
4703
|
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
4623
4704
|
function ReviewMergeRequestActionButton({
|
|
4624
4705
|
accessibilityLabel,
|
|
@@ -4628,14 +4709,14 @@ function ReviewMergeRequestActionButton({
|
|
|
4628
4709
|
children,
|
|
4629
4710
|
iconOnly
|
|
4630
4711
|
}) {
|
|
4631
|
-
const [pressed, setPressed] =
|
|
4712
|
+
const [pressed, setPressed] = React26.useState(false);
|
|
4632
4713
|
const height = iconOnly ? 36 : 40;
|
|
4633
4714
|
const width = iconOnly ? 36 : void 0;
|
|
4634
4715
|
const paddingHorizontal = iconOnly ? 0 : 16;
|
|
4635
4716
|
const paddingVertical = iconOnly ? 0 : 8;
|
|
4636
4717
|
const opacity = disabled ? 0.5 : pressed ? 0.9 : 1;
|
|
4637
4718
|
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
4638
|
-
|
|
4719
|
+
import_react_native37.View,
|
|
4639
4720
|
{
|
|
4640
4721
|
style: {
|
|
4641
4722
|
width,
|
|
@@ -4650,7 +4731,7 @@ function ReviewMergeRequestActionButton({
|
|
|
4650
4731
|
justifyContent: "center"
|
|
4651
4732
|
},
|
|
4652
4733
|
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
4653
|
-
|
|
4734
|
+
import_react_native37.Pressable,
|
|
4654
4735
|
{
|
|
4655
4736
|
accessibilityRole: "button",
|
|
4656
4737
|
accessibilityLabel,
|
|
@@ -4690,14 +4771,14 @@ function ReviewMergeRequestCard({
|
|
|
4690
4771
|
onTest
|
|
4691
4772
|
}) {
|
|
4692
4773
|
const theme = useTheme();
|
|
4693
|
-
const status =
|
|
4774
|
+
const status = React27.useMemo(() => getMergeRequestStatusDisplay(mr.status), [mr.status]);
|
|
4694
4775
|
const canAct = mr.status === "open";
|
|
4695
|
-
const rotate =
|
|
4696
|
-
|
|
4697
|
-
|
|
4776
|
+
const rotate = React27.useRef(new import_react_native38.Animated.Value(isExpanded ? 1 : 0)).current;
|
|
4777
|
+
React27.useEffect(() => {
|
|
4778
|
+
import_react_native38.Animated.timing(rotate, { toValue: isExpanded ? 1 : 0, duration: 200, useNativeDriver: true }).start();
|
|
4698
4779
|
}, [isExpanded, rotate]);
|
|
4699
4780
|
const position = total > 1 ? `${index + 1}/${total}` : "Merge request";
|
|
4700
|
-
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4781
|
+
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
4782
|
Card,
|
|
4702
4783
|
{
|
|
4703
4784
|
padded: false,
|
|
@@ -4710,9 +4791,9 @@ function ReviewMergeRequestCard({
|
|
|
4710
4791
|
}
|
|
4711
4792
|
],
|
|
4712
4793
|
children: [
|
|
4713
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4794
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [
|
|
4714
4795
|
/* @__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)(
|
|
4796
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
4716
4797
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4717
4798
|
Text,
|
|
4718
4799
|
{
|
|
@@ -4728,7 +4809,7 @@ function ReviewMergeRequestCard({
|
|
|
4728
4809
|
] })
|
|
4729
4810
|
] }),
|
|
4730
4811
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4731
|
-
|
|
4812
|
+
import_react_native38.Animated.View,
|
|
4732
4813
|
{
|
|
4733
4814
|
style: {
|
|
4734
4815
|
transform: [{ rotate: rotate.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "180deg"] }) }]
|
|
@@ -4737,7 +4818,7 @@ function ReviewMergeRequestCard({
|
|
|
4737
4818
|
}
|
|
4738
4819
|
)
|
|
4739
4820
|
] }),
|
|
4740
|
-
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4821
|
+
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { marginTop: 16 }, children: [
|
|
4741
4822
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4742
4823
|
Text,
|
|
4743
4824
|
{
|
|
@@ -4755,9 +4836,9 @@ function ReviewMergeRequestCard({
|
|
|
4755
4836
|
/* @__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
4837
|
mr.description ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(MarkdownText, { markdown: mr.description, variant: "mergeRequest" }) : null
|
|
4757
4838
|
] }) : null,
|
|
4758
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4759
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4760
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4839
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native38.View, { style: { height: 1, backgroundColor: withAlpha(theme.colors.borderStrong, 0.5), marginTop: 12, marginBottom: 12 } }),
|
|
4840
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
4841
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", gap: 8 }, children: [
|
|
4761
4842
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4762
4843
|
ReviewMergeRequestActionButton,
|
|
4763
4844
|
{
|
|
@@ -4766,7 +4847,7 @@ function ReviewMergeRequestCard({
|
|
|
4766
4847
|
disabled: !canAct || isAnyProcessing,
|
|
4767
4848
|
onPress: onReject,
|
|
4768
4849
|
iconOnly: !isExpanded,
|
|
4769
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4850
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4770
4851
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native8.X, { size: 18, color: "#FFFFFF" }),
|
|
4771
4852
|
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Reject" }) : null
|
|
4772
4853
|
] })
|
|
@@ -4780,10 +4861,10 @@ function ReviewMergeRequestCard({
|
|
|
4780
4861
|
disabled: !canAct || isAnyProcessing,
|
|
4781
4862
|
onPress: onApprove,
|
|
4782
4863
|
iconOnly: !isExpanded,
|
|
4783
|
-
children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
4784
|
-
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4864
|
+
children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4865
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native38.ActivityIndicator, { size: "small", color: "#FFFFFF" }),
|
|
4785
4866
|
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)(
|
|
4867
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
|
|
4787
4868
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native8.Check, { size: 18, color: "#FFFFFF" }),
|
|
4788
4869
|
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Approve" }) : null
|
|
4789
4870
|
] })
|
|
@@ -4798,7 +4879,7 @@ function ReviewMergeRequestCard({
|
|
|
4798
4879
|
disabled: isBuilding || isTestingThis,
|
|
4799
4880
|
onPress: onTest,
|
|
4800
4881
|
iconOnly: !isExpanded,
|
|
4801
|
-
children: isTestingThis ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
|
|
4882
|
+
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
4883
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native8.Play, { size: 14, color: theme.colors.text }),
|
|
4803
4884
|
isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: theme.colors.text, fontWeight: theme.typography.fontWeight.semibold }, children: "Test" }) : null
|
|
4804
4885
|
] })
|
|
@@ -4824,32 +4905,32 @@ function ReviewMergeRequestCarousel({
|
|
|
4824
4905
|
style
|
|
4825
4906
|
}) {
|
|
4826
4907
|
const theme = useTheme();
|
|
4827
|
-
const { width } = (0,
|
|
4828
|
-
const [expanded, setExpanded] =
|
|
4829
|
-
const carouselScrollX =
|
|
4908
|
+
const { width } = (0, import_react_native39.useWindowDimensions)();
|
|
4909
|
+
const [expanded, setExpanded] = React28.useState({});
|
|
4910
|
+
const carouselScrollX = React28.useRef(new import_react_native39.Animated.Value(0)).current;
|
|
4830
4911
|
const peekAmount = 24;
|
|
4831
4912
|
const gap = 16;
|
|
4832
|
-
const cardWidth =
|
|
4913
|
+
const cardWidth = React28.useMemo(() => Math.max(1, width - theme.spacing.lg * 2 - peekAmount), [peekAmount, theme.spacing.lg, width]);
|
|
4833
4914
|
const snapInterval = cardWidth + gap;
|
|
4834
4915
|
const dotColor = theme.scheme === "dark" ? "#FFFFFF" : "#000000";
|
|
4835
4916
|
if (mergeRequests.length === 0) return null;
|
|
4836
|
-
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
4917
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native39.View, { style: [{ marginHorizontal: -theme.spacing.lg }, style], children: [
|
|
4837
4918
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4838
|
-
|
|
4919
|
+
import_react_native39.FlatList,
|
|
4839
4920
|
{
|
|
4840
4921
|
horizontal: true,
|
|
4841
4922
|
data: mergeRequests,
|
|
4842
4923
|
keyExtractor: (mr) => mr.id,
|
|
4843
4924
|
showsHorizontalScrollIndicator: false,
|
|
4844
4925
|
contentContainerStyle: { paddingHorizontal: theme.spacing.lg, paddingVertical: theme.spacing.sm },
|
|
4845
|
-
ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4926
|
+
ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native39.View, { style: { width: gap } }),
|
|
4846
4927
|
snapToAlignment: "start",
|
|
4847
4928
|
decelerationRate: "fast",
|
|
4848
4929
|
snapToInterval: snapInterval,
|
|
4849
4930
|
disableIntervalMomentum: true,
|
|
4850
4931
|
style: { paddingRight: peekAmount },
|
|
4851
|
-
ListFooterComponent: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4852
|
-
onScroll:
|
|
4932
|
+
ListFooterComponent: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native39.View, { style: { width: peekAmount } }),
|
|
4933
|
+
onScroll: import_react_native39.Animated.event([{ nativeEvent: { contentOffset: { x: carouselScrollX } } }], {
|
|
4853
4934
|
useNativeDriver: false
|
|
4854
4935
|
}),
|
|
4855
4936
|
scrollEventThrottle: 16,
|
|
@@ -4860,7 +4941,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4860
4941
|
const isProcessing = Boolean(processingMrId && processingMrId === item.id);
|
|
4861
4942
|
const isAnyProcessing = Boolean(processingMrId);
|
|
4862
4943
|
const isTestingThis = Boolean(testingMrId && testingMrId === item.id);
|
|
4863
|
-
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4944
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native39.View, { style: { width: cardWidth }, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4864
4945
|
ReviewMergeRequestCard,
|
|
4865
4946
|
{
|
|
4866
4947
|
mr: item,
|
|
@@ -4881,7 +4962,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4881
4962
|
}
|
|
4882
4963
|
}
|
|
4883
4964
|
),
|
|
4884
|
-
mergeRequests.length >= 1 ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4965
|
+
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
4966
|
const inputRange = [(index - 1) * snapInterval, index * snapInterval, (index + 1) * snapInterval];
|
|
4886
4967
|
const scale = carouselScrollX.interpolate({
|
|
4887
4968
|
inputRange,
|
|
@@ -4894,7 +4975,7 @@ function ReviewMergeRequestCarousel({
|
|
|
4894
4975
|
extrapolate: "clamp"
|
|
4895
4976
|
});
|
|
4896
4977
|
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4897
|
-
|
|
4978
|
+
import_react_native39.Animated.View,
|
|
4898
4979
|
{
|
|
4899
4980
|
style: {
|
|
4900
4981
|
width: 8,
|
|
@@ -4928,7 +5009,7 @@ function PreviewCollaborateSection({
|
|
|
4928
5009
|
onTestMr
|
|
4929
5010
|
}) {
|
|
4930
5011
|
const theme = useTheme();
|
|
4931
|
-
const [submittingMr, setSubmittingMr] =
|
|
5012
|
+
const [submittingMr, setSubmittingMr] = React29.useState(false);
|
|
4932
5013
|
const hasSection = canSubmitMergeRequest || incomingMergeRequests.length > 0 || outgoingMergeRequests.length > 0;
|
|
4933
5014
|
if (!hasSection) return null;
|
|
4934
5015
|
const showActionsSubtitle = canSubmitMergeRequest && onSubmitMergeRequest || onTestMr && incomingMergeRequests.length > 0;
|
|
@@ -4955,7 +5036,7 @@ function PreviewCollaborateSection({
|
|
|
4955
5036
|
accessibilityLabel: "Submit merge request",
|
|
4956
5037
|
disabled: submittingMr,
|
|
4957
5038
|
onPress: () => {
|
|
4958
|
-
|
|
5039
|
+
import_react_native40.Alert.alert(
|
|
4959
5040
|
"Submit Merge Request",
|
|
4960
5041
|
"Are you sure you want to submit your changes to the original app?",
|
|
4961
5042
|
[
|
|
@@ -4981,7 +5062,7 @@ function PreviewCollaborateSection({
|
|
|
4981
5062
|
marginBottom: theme.spacing.sm
|
|
4982
5063
|
},
|
|
4983
5064
|
left: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
4984
|
-
|
|
5065
|
+
import_react_native40.View,
|
|
4985
5066
|
{
|
|
4986
5067
|
style: {
|
|
4987
5068
|
width: 40,
|
|
@@ -4992,7 +5073,7 @@ function PreviewCollaborateSection({
|
|
|
4992
5073
|
backgroundColor: withAlpha("#03DAC6", 0.1),
|
|
4993
5074
|
marginRight: theme.spacing.lg
|
|
4994
5075
|
},
|
|
4995
|
-
children: submittingMr ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5076
|
+
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
5077
|
}
|
|
4997
5078
|
),
|
|
4998
5079
|
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 +5111,13 @@ function PreviewCollaborateSection({
|
|
|
5030
5111
|
children: "History"
|
|
5031
5112
|
}
|
|
5032
5113
|
),
|
|
5033
|
-
outgoingMergeRequests.map((mr) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
5114
|
+
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
5115
|
] }) : null
|
|
5035
5116
|
] });
|
|
5036
5117
|
}
|
|
5037
5118
|
|
|
5038
5119
|
// src/studio/ui/preview-panel/usePreviewPanelData.ts
|
|
5039
|
-
var
|
|
5120
|
+
var React31 = __toESM(require("react"));
|
|
5040
5121
|
|
|
5041
5122
|
// src/data/apps/images/remote.ts
|
|
5042
5123
|
var AppImagesRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -5087,7 +5168,7 @@ var AppImagesRepositoryImpl = class extends BaseRepository {
|
|
|
5087
5168
|
var appImagesRepository = new AppImagesRepositoryImpl(appImagesRemoteDataSource);
|
|
5088
5169
|
|
|
5089
5170
|
// src/studio/hooks/useAppStats.ts
|
|
5090
|
-
var
|
|
5171
|
+
var React30 = __toESM(require("react"));
|
|
5091
5172
|
var Haptics2 = __toESM(require("expo-haptics"));
|
|
5092
5173
|
|
|
5093
5174
|
// src/data/likes/remote.ts
|
|
@@ -5156,34 +5237,34 @@ function useAppStats({
|
|
|
5156
5237
|
initialIsLiked = false,
|
|
5157
5238
|
onOpenComments
|
|
5158
5239
|
}) {
|
|
5159
|
-
const [likeCount, setLikeCount] =
|
|
5160
|
-
const [commentCount, setCommentCount] =
|
|
5161
|
-
const [forkCount, setForkCount] =
|
|
5162
|
-
const [isLiked, setIsLiked] =
|
|
5163
|
-
const didMutateRef =
|
|
5164
|
-
const lastAppIdRef =
|
|
5165
|
-
|
|
5240
|
+
const [likeCount, setLikeCount] = React30.useState(initialLikes);
|
|
5241
|
+
const [commentCount, setCommentCount] = React30.useState(initialComments);
|
|
5242
|
+
const [forkCount, setForkCount] = React30.useState(initialForks);
|
|
5243
|
+
const [isLiked, setIsLiked] = React30.useState(initialIsLiked);
|
|
5244
|
+
const didMutateRef = React30.useRef(false);
|
|
5245
|
+
const lastAppIdRef = React30.useRef("");
|
|
5246
|
+
React30.useEffect(() => {
|
|
5166
5247
|
if (lastAppIdRef.current === appId) return;
|
|
5167
5248
|
lastAppIdRef.current = appId;
|
|
5168
5249
|
didMutateRef.current = false;
|
|
5169
5250
|
}, [appId]);
|
|
5170
|
-
|
|
5251
|
+
React30.useEffect(() => {
|
|
5171
5252
|
if (didMutateRef.current) return;
|
|
5172
5253
|
setLikeCount(initialLikes);
|
|
5173
5254
|
}, [appId, initialLikes]);
|
|
5174
|
-
|
|
5255
|
+
React30.useEffect(() => {
|
|
5175
5256
|
if (didMutateRef.current) return;
|
|
5176
5257
|
setCommentCount(initialComments);
|
|
5177
5258
|
}, [appId, initialComments]);
|
|
5178
|
-
|
|
5259
|
+
React30.useEffect(() => {
|
|
5179
5260
|
if (didMutateRef.current) return;
|
|
5180
5261
|
setForkCount(initialForks);
|
|
5181
5262
|
}, [appId, initialForks]);
|
|
5182
|
-
|
|
5263
|
+
React30.useEffect(() => {
|
|
5183
5264
|
if (didMutateRef.current) return;
|
|
5184
5265
|
setIsLiked(initialIsLiked);
|
|
5185
5266
|
}, [appId, initialIsLiked]);
|
|
5186
|
-
const handleLike =
|
|
5267
|
+
const handleLike = React30.useCallback(async () => {
|
|
5187
5268
|
var _a, _b;
|
|
5188
5269
|
if (!appId) return;
|
|
5189
5270
|
didMutateRef.current = true;
|
|
@@ -5207,7 +5288,7 @@ function useAppStats({
|
|
|
5207
5288
|
setLikeCount((prev) => Math.max(0, prev + (newIsLiked ? -1 : 1)));
|
|
5208
5289
|
}
|
|
5209
5290
|
}, [appId, isLiked, likeCount]);
|
|
5210
|
-
const handleOpenComments =
|
|
5291
|
+
const handleOpenComments = React30.useCallback(() => {
|
|
5211
5292
|
if (!appId) return;
|
|
5212
5293
|
try {
|
|
5213
5294
|
void Haptics2.impactAsync(Haptics2.ImpactFeedbackStyle.Light);
|
|
@@ -5222,11 +5303,11 @@ function useAppStats({
|
|
|
5222
5303
|
var LIKE_DEBUG_PREFIX = "[COMERGE_LIKE_DEBUG]";
|
|
5223
5304
|
function usePreviewPanelData(params) {
|
|
5224
5305
|
const { app, isOwner, outgoingMergeRequests, onOpenComments, commentCountOverride } = params;
|
|
5225
|
-
const [imageUrl, setImageUrl] =
|
|
5226
|
-
const [imageLoaded, setImageLoaded] =
|
|
5227
|
-
const [insights, setInsights] =
|
|
5228
|
-
const [creator, setCreator] =
|
|
5229
|
-
|
|
5306
|
+
const [imageUrl, setImageUrl] = React31.useState(null);
|
|
5307
|
+
const [imageLoaded, setImageLoaded] = React31.useState(false);
|
|
5308
|
+
const [insights, setInsights] = React31.useState({ likes: 0, comments: 0, forks: 0, downloads: 0 });
|
|
5309
|
+
const [creator, setCreator] = React31.useState(null);
|
|
5310
|
+
React31.useEffect(() => {
|
|
5230
5311
|
if (!(app == null ? void 0 : app.id)) return;
|
|
5231
5312
|
let cancelled = false;
|
|
5232
5313
|
(async () => {
|
|
@@ -5241,7 +5322,7 @@ function usePreviewPanelData(params) {
|
|
|
5241
5322
|
cancelled = true;
|
|
5242
5323
|
};
|
|
5243
5324
|
}, [app == null ? void 0 : app.id]);
|
|
5244
|
-
|
|
5325
|
+
React31.useEffect(() => {
|
|
5245
5326
|
if (!(app == null ? void 0 : app.createdBy)) return;
|
|
5246
5327
|
let cancelled = false;
|
|
5247
5328
|
(async () => {
|
|
@@ -5257,10 +5338,10 @@ function usePreviewPanelData(params) {
|
|
|
5257
5338
|
cancelled = true;
|
|
5258
5339
|
};
|
|
5259
5340
|
}, [app == null ? void 0 : app.createdBy]);
|
|
5260
|
-
|
|
5341
|
+
React31.useEffect(() => {
|
|
5261
5342
|
setImageLoaded(false);
|
|
5262
5343
|
}, [app == null ? void 0 : app.id]);
|
|
5263
|
-
|
|
5344
|
+
React31.useEffect(() => {
|
|
5264
5345
|
if (!(app == null ? void 0 : app.id)) return;
|
|
5265
5346
|
let cancelled = false;
|
|
5266
5347
|
(async () => {
|
|
@@ -5285,7 +5366,7 @@ function usePreviewPanelData(params) {
|
|
|
5285
5366
|
cancelled = true;
|
|
5286
5367
|
};
|
|
5287
5368
|
}, [app == null ? void 0 : app.id]);
|
|
5288
|
-
|
|
5369
|
+
React31.useEffect(() => {
|
|
5289
5370
|
if (!(app == null ? void 0 : app.id)) return;
|
|
5290
5371
|
log.debug(
|
|
5291
5372
|
`${LIKE_DEBUG_PREFIX} usePreviewPanelData.appChanged appId=${app.id} app.isLiked=${String(app.isLiked)}`
|
|
@@ -5299,7 +5380,7 @@ function usePreviewPanelData(params) {
|
|
|
5299
5380
|
initialIsLiked: Boolean(app == null ? void 0 : app.isLiked),
|
|
5300
5381
|
onOpenComments
|
|
5301
5382
|
});
|
|
5302
|
-
const canSubmitMergeRequest =
|
|
5383
|
+
const canSubmitMergeRequest = React31.useMemo(() => {
|
|
5303
5384
|
if (!isOwner) return false;
|
|
5304
5385
|
if (!app) return false;
|
|
5305
5386
|
if (!app.forkedFromAppId) return false;
|
|
@@ -5354,9 +5435,9 @@ function PreviewPanel({
|
|
|
5354
5435
|
});
|
|
5355
5436
|
const header = /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PreviewPanelHeader, { isOwner, onClose, onNavigateHome, onGoToChat });
|
|
5356
5437
|
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)(
|
|
5438
|
+
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: [
|
|
5439
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native41.ActivityIndicator, {}),
|
|
5440
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native41.View, { style: { height: 12 } }),
|
|
5360
5441
|
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Text, { variant: "bodyMuted", children: "Loading app\u2026" })
|
|
5361
5442
|
] }) });
|
|
5362
5443
|
}
|
|
@@ -5412,22 +5493,22 @@ function PreviewPanel({
|
|
|
5412
5493
|
}
|
|
5413
5494
|
|
|
5414
5495
|
// src/studio/ui/ChatPanel.tsx
|
|
5415
|
-
var
|
|
5416
|
-
var
|
|
5496
|
+
var React36 = __toESM(require("react"));
|
|
5497
|
+
var import_react_native49 = require("react-native");
|
|
5417
5498
|
|
|
5418
5499
|
// src/components/chat/ChatPage.tsx
|
|
5419
|
-
var
|
|
5420
|
-
var
|
|
5500
|
+
var React34 = __toESM(require("react"));
|
|
5501
|
+
var import_react_native45 = require("react-native");
|
|
5421
5502
|
var import_react_native_safe_area_context4 = require("react-native-safe-area-context");
|
|
5422
5503
|
var import_react_native_reanimated2 = __toESM(require("react-native-reanimated"));
|
|
5423
5504
|
|
|
5424
5505
|
// src/components/chat/ChatMessageList.tsx
|
|
5425
|
-
var
|
|
5426
|
-
var
|
|
5506
|
+
var React33 = __toESM(require("react"));
|
|
5507
|
+
var import_react_native44 = require("react-native");
|
|
5427
5508
|
var import_bottom_sheet5 = require("@gorhom/bottom-sheet");
|
|
5428
5509
|
|
|
5429
5510
|
// src/components/chat/ChatMessageBubble.tsx
|
|
5430
|
-
var
|
|
5511
|
+
var import_react_native42 = require("react-native");
|
|
5431
5512
|
var import_lucide_react_native10 = require("lucide-react-native");
|
|
5432
5513
|
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
5433
5514
|
function ChatMessageBubble({ message, renderContent, style }) {
|
|
@@ -5443,7 +5524,7 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5443
5524
|
const bubbleVariant = isHuman ? "surface" : "surfaceRaised";
|
|
5444
5525
|
const cornerStyle = isHuman ? { borderTopRightRadius: 0 } : { borderTopLeftRadius: 0 };
|
|
5445
5526
|
const bodyColor = metaStatus === "success" ? theme.colors.success : metaStatus === "error" ? theme.colors.danger : void 0;
|
|
5446
|
-
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native42.View, { style: [align, style], children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
5447
5528
|
Surface,
|
|
5448
5529
|
{
|
|
5449
5530
|
variant: bubbleVariant,
|
|
@@ -5458,34 +5539,34 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5458
5539
|
},
|
|
5459
5540
|
cornerStyle
|
|
5460
5541
|
],
|
|
5461
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
5542
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native42.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5462
5543
|
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
5544
|
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)(
|
|
5545
|
+
/* @__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
5546
|
] })
|
|
5466
5547
|
}
|
|
5467
5548
|
) });
|
|
5468
5549
|
}
|
|
5469
5550
|
|
|
5470
5551
|
// src/components/chat/TypingIndicator.tsx
|
|
5471
|
-
var
|
|
5472
|
-
var
|
|
5552
|
+
var React32 = __toESM(require("react"));
|
|
5553
|
+
var import_react_native43 = require("react-native");
|
|
5473
5554
|
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
5474
5555
|
function TypingIndicator({ style }) {
|
|
5475
5556
|
const theme = useTheme();
|
|
5476
5557
|
const dotColor = theme.colors.textSubtle;
|
|
5477
|
-
const anims =
|
|
5478
|
-
() => [new
|
|
5558
|
+
const anims = React32.useMemo(
|
|
5559
|
+
() => [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
5560
|
[]
|
|
5480
5561
|
);
|
|
5481
|
-
|
|
5562
|
+
React32.useEffect(() => {
|
|
5482
5563
|
const loops = [];
|
|
5483
5564
|
anims.forEach((a, idx) => {
|
|
5484
|
-
const seq =
|
|
5485
|
-
|
|
5486
|
-
|
|
5565
|
+
const seq = import_react_native43.Animated.sequence([
|
|
5566
|
+
import_react_native43.Animated.timing(a, { toValue: 1, duration: 420, useNativeDriver: true, delay: idx * 140 }),
|
|
5567
|
+
import_react_native43.Animated.timing(a, { toValue: 0.3, duration: 420, useNativeDriver: true })
|
|
5487
5568
|
]);
|
|
5488
|
-
const loop =
|
|
5569
|
+
const loop = import_react_native43.Animated.loop(seq);
|
|
5489
5570
|
loops.push(loop);
|
|
5490
5571
|
loop.start();
|
|
5491
5572
|
});
|
|
@@ -5493,8 +5574,8 @@ function TypingIndicator({ style }) {
|
|
|
5493
5574
|
loops.forEach((l) => l.stop());
|
|
5494
5575
|
};
|
|
5495
5576
|
}, [anims]);
|
|
5496
|
-
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
5497
|
-
|
|
5577
|
+
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)(
|
|
5578
|
+
import_react_native43.Animated.View,
|
|
5498
5579
|
{
|
|
5499
5580
|
style: {
|
|
5500
5581
|
width: 8,
|
|
@@ -5503,7 +5584,7 @@ function TypingIndicator({ style }) {
|
|
|
5503
5584
|
marginHorizontal: 3,
|
|
5504
5585
|
backgroundColor: dotColor,
|
|
5505
5586
|
opacity: a,
|
|
5506
|
-
transform: [{ translateY:
|
|
5587
|
+
transform: [{ translateY: import_react_native43.Animated.multiply(import_react_native43.Animated.subtract(a, 0.3), 2) }]
|
|
5507
5588
|
}
|
|
5508
5589
|
},
|
|
5509
5590
|
i
|
|
@@ -5512,39 +5593,43 @@ function TypingIndicator({ style }) {
|
|
|
5512
5593
|
|
|
5513
5594
|
// src/components/chat/ChatMessageList.tsx
|
|
5514
5595
|
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
5515
|
-
var ChatMessageList =
|
|
5596
|
+
var ChatMessageList = React33.forwardRef(
|
|
5516
5597
|
({
|
|
5517
5598
|
messages,
|
|
5518
5599
|
showTypingIndicator = false,
|
|
5519
5600
|
renderMessageContent,
|
|
5520
5601
|
contentStyle,
|
|
5602
|
+
bottomInset = 0,
|
|
5521
5603
|
onNearBottomChange,
|
|
5522
5604
|
nearBottomThreshold = 200
|
|
5523
5605
|
}, ref) => {
|
|
5524
5606
|
const theme = useTheme();
|
|
5525
|
-
const listRef =
|
|
5526
|
-
const nearBottomRef =
|
|
5527
|
-
const initialScrollDoneRef =
|
|
5528
|
-
const lastMessageIdRef =
|
|
5529
|
-
const scrollToBottom =
|
|
5607
|
+
const listRef = React33.useRef(null);
|
|
5608
|
+
const nearBottomRef = React33.useRef(true);
|
|
5609
|
+
const initialScrollDoneRef = React33.useRef(false);
|
|
5610
|
+
const lastMessageIdRef = React33.useRef(null);
|
|
5611
|
+
const scrollToBottom = React33.useCallback((options) => {
|
|
5530
5612
|
var _a;
|
|
5531
5613
|
const animated = (options == null ? void 0 : options.animated) ?? true;
|
|
5532
5614
|
(_a = listRef.current) == null ? void 0 : _a.scrollToEnd({ animated });
|
|
5533
5615
|
}, []);
|
|
5534
|
-
|
|
5535
|
-
const handleScroll =
|
|
5616
|
+
React33.useImperativeHandle(ref, () => ({ scrollToBottom }), [scrollToBottom]);
|
|
5617
|
+
const handleScroll = React33.useCallback(
|
|
5536
5618
|
(e) => {
|
|
5537
5619
|
const { contentOffset, contentSize, layoutMeasurement } = e.nativeEvent;
|
|
5538
|
-
const distanceFromBottom = Math.max(
|
|
5620
|
+
const distanceFromBottom = Math.max(
|
|
5621
|
+
contentSize.height - Math.max(bottomInset, 0) - (contentOffset.y + layoutMeasurement.height),
|
|
5622
|
+
0
|
|
5623
|
+
);
|
|
5539
5624
|
const isNear = distanceFromBottom <= nearBottomThreshold;
|
|
5540
5625
|
if (nearBottomRef.current !== isNear) {
|
|
5541
5626
|
nearBottomRef.current = isNear;
|
|
5542
5627
|
onNearBottomChange == null ? void 0 : onNearBottomChange(isNear);
|
|
5543
5628
|
}
|
|
5544
5629
|
},
|
|
5545
|
-
[nearBottomThreshold, onNearBottomChange]
|
|
5630
|
+
[bottomInset, nearBottomThreshold, onNearBottomChange]
|
|
5546
5631
|
);
|
|
5547
|
-
|
|
5632
|
+
React33.useEffect(() => {
|
|
5548
5633
|
var _a;
|
|
5549
5634
|
if (initialScrollDoneRef.current) return;
|
|
5550
5635
|
if (messages.length === 0) return;
|
|
@@ -5553,7 +5638,7 @@ var ChatMessageList = React32.forwardRef(
|
|
|
5553
5638
|
const id = requestAnimationFrame(() => scrollToBottom({ animated: false }));
|
|
5554
5639
|
return () => cancelAnimationFrame(id);
|
|
5555
5640
|
}, [messages, scrollToBottom]);
|
|
5556
|
-
|
|
5641
|
+
React33.useEffect(() => {
|
|
5557
5642
|
if (!initialScrollDoneRef.current) return;
|
|
5558
5643
|
const lastId = messages.length > 0 ? messages[messages.length - 1].id : null;
|
|
5559
5644
|
const prevLastId = lastMessageIdRef.current;
|
|
@@ -5563,13 +5648,19 @@ var ChatMessageList = React32.forwardRef(
|
|
|
5563
5648
|
const id = requestAnimationFrame(() => scrollToBottom({ animated: true }));
|
|
5564
5649
|
return () => cancelAnimationFrame(id);
|
|
5565
5650
|
}, [messages, scrollToBottom]);
|
|
5566
|
-
|
|
5651
|
+
React33.useEffect(() => {
|
|
5567
5652
|
if (showTypingIndicator && nearBottomRef.current) {
|
|
5568
5653
|
const id = requestAnimationFrame(() => scrollToBottom({ animated: true }));
|
|
5569
5654
|
return () => cancelAnimationFrame(id);
|
|
5570
5655
|
}
|
|
5571
5656
|
return void 0;
|
|
5572
5657
|
}, [showTypingIndicator, scrollToBottom]);
|
|
5658
|
+
React33.useEffect(() => {
|
|
5659
|
+
if (!initialScrollDoneRef.current) return;
|
|
5660
|
+
if (!nearBottomRef.current) return;
|
|
5661
|
+
const id = requestAnimationFrame(() => scrollToBottom({ animated: false }));
|
|
5662
|
+
return () => cancelAnimationFrame(id);
|
|
5663
|
+
}, [bottomInset, scrollToBottom]);
|
|
5573
5664
|
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
5574
5665
|
import_bottom_sheet5.BottomSheetFlatList,
|
|
5575
5666
|
{
|
|
@@ -5583,13 +5674,15 @@ var ChatMessageList = React32.forwardRef(
|
|
|
5583
5674
|
{
|
|
5584
5675
|
paddingHorizontal: theme.spacing.lg,
|
|
5585
5676
|
paddingTop: theme.spacing.sm,
|
|
5586
|
-
paddingBottom: theme.spacing.
|
|
5677
|
+
paddingBottom: theme.spacing.sm
|
|
5587
5678
|
},
|
|
5588
5679
|
contentStyle
|
|
5589
5680
|
],
|
|
5590
|
-
renderItem: ({ item, index }) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
5591
|
-
ListFooterComponent:
|
|
5592
|
-
|
|
5681
|
+
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 }) }),
|
|
5682
|
+
ListFooterComponent: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_react_native44.View, { children: [
|
|
5683
|
+
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,
|
|
5684
|
+
bottomInset > 0 ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native44.View, { style: { height: bottomInset } }) : null
|
|
5685
|
+
] })
|
|
5593
5686
|
}
|
|
5594
5687
|
);
|
|
5595
5688
|
}
|
|
@@ -5612,37 +5705,38 @@ function ChatPage({
|
|
|
5612
5705
|
}) {
|
|
5613
5706
|
const theme = useTheme();
|
|
5614
5707
|
const insets = (0, import_react_native_safe_area_context4.useSafeAreaInsets)();
|
|
5615
|
-
const [composerHeight, setComposerHeight] =
|
|
5616
|
-
const [keyboardVisible, setKeyboardVisible] =
|
|
5708
|
+
const [composerHeight, setComposerHeight] = React34.useState(0);
|
|
5709
|
+
const [keyboardVisible, setKeyboardVisible] = React34.useState(false);
|
|
5617
5710
|
const animatedKeyboard = (0, import_react_native_reanimated2.useAnimatedKeyboard)();
|
|
5618
|
-
|
|
5619
|
-
if (
|
|
5620
|
-
const show =
|
|
5621
|
-
const hide =
|
|
5711
|
+
React34.useEffect(() => {
|
|
5712
|
+
if (import_react_native45.Platform.OS !== "ios") return;
|
|
5713
|
+
const show = import_react_native45.Keyboard.addListener("keyboardWillShow", () => setKeyboardVisible(true));
|
|
5714
|
+
const hide = import_react_native45.Keyboard.addListener("keyboardWillHide", () => setKeyboardVisible(false));
|
|
5622
5715
|
return () => {
|
|
5623
5716
|
show.remove();
|
|
5624
5717
|
hide.remove();
|
|
5625
5718
|
};
|
|
5626
5719
|
}, []);
|
|
5627
|
-
const footerBottomPadding =
|
|
5720
|
+
const footerBottomPadding = import_react_native45.Platform.OS === "ios" ? keyboardVisible ? 0 : insets.bottom : insets.bottom + 10;
|
|
5628
5721
|
const footerAnimatedStyle = (0, import_react_native_reanimated2.useAnimatedStyle)(() => {
|
|
5629
|
-
if (
|
|
5722
|
+
if (import_react_native45.Platform.OS !== "ios") return { paddingBottom: insets.bottom + 10 };
|
|
5630
5723
|
return { paddingBottom: animatedKeyboard.height.value > 0 ? 0 : insets.bottom };
|
|
5631
5724
|
});
|
|
5632
5725
|
const overlayBottom = composerHeight + footerBottomPadding + theme.spacing.lg;
|
|
5633
|
-
const
|
|
5726
|
+
const bottomInset = composerHeight + footerBottomPadding + theme.spacing.xl;
|
|
5727
|
+
const resolvedOverlay = React34.useMemo(() => {
|
|
5634
5728
|
var _a;
|
|
5635
5729
|
if (!overlay) return null;
|
|
5636
|
-
if (!
|
|
5730
|
+
if (!React34.isValidElement(overlay)) return overlay;
|
|
5637
5731
|
const prevStyle = (_a = overlay.props) == null ? void 0 : _a.style;
|
|
5638
|
-
return
|
|
5732
|
+
return React34.cloneElement(overlay, {
|
|
5639
5733
|
style: [prevStyle, { bottom: overlayBottom }]
|
|
5640
5734
|
});
|
|
5641
5735
|
}, [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)(
|
|
5736
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native45.View, { style: [{ flex: 1 }, style], children: [
|
|
5737
|
+
header ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native45.View, { children: header }) : null,
|
|
5738
|
+
topBanner ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native45.View, { style: { paddingHorizontal: theme.spacing.lg, paddingTop: theme.spacing.sm }, children: topBanner }) : null,
|
|
5739
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native45.View, { style: { flex: 1 }, children: [
|
|
5646
5740
|
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
5647
5741
|
ChatMessageList,
|
|
5648
5742
|
{
|
|
@@ -5651,7 +5745,7 @@ function ChatPage({
|
|
|
5651
5745
|
showTypingIndicator,
|
|
5652
5746
|
renderMessageContent,
|
|
5653
5747
|
onNearBottomChange,
|
|
5654
|
-
|
|
5748
|
+
bottomInset
|
|
5655
5749
|
}
|
|
5656
5750
|
),
|
|
5657
5751
|
resolvedOverlay,
|
|
@@ -5684,15 +5778,15 @@ function ChatPage({
|
|
|
5684
5778
|
}
|
|
5685
5779
|
|
|
5686
5780
|
// src/components/chat/ScrollToBottomButton.tsx
|
|
5687
|
-
var
|
|
5688
|
-
var
|
|
5781
|
+
var React35 = __toESM(require("react"));
|
|
5782
|
+
var import_react_native46 = require("react-native");
|
|
5689
5783
|
var import_react_native_reanimated3 = __toESM(require("react-native-reanimated"));
|
|
5690
5784
|
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
5691
5785
|
function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
5692
5786
|
const theme = useTheme();
|
|
5693
5787
|
const progress = (0, import_react_native_reanimated3.useSharedValue)(visible ? 1 : 0);
|
|
5694
|
-
const [pressed, setPressed] =
|
|
5695
|
-
|
|
5788
|
+
const [pressed, setPressed] = React35.useState(false);
|
|
5789
|
+
React35.useEffect(() => {
|
|
5696
5790
|
progress.value = (0, import_react_native_reanimated3.withTiming)(visible ? 1 : 0, { duration: 200, easing: import_react_native_reanimated3.Easing.out(import_react_native_reanimated3.Easing.ease) });
|
|
5697
5791
|
}, [progress, visible]);
|
|
5698
5792
|
const animStyle = (0, import_react_native_reanimated3.useAnimatedStyle)(() => ({
|
|
@@ -5716,7 +5810,7 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5716
5810
|
animStyle
|
|
5717
5811
|
],
|
|
5718
5812
|
children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
5719
|
-
|
|
5813
|
+
import_react_native46.View,
|
|
5720
5814
|
{
|
|
5721
5815
|
style: {
|
|
5722
5816
|
width: 44,
|
|
@@ -5735,7 +5829,7 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5735
5829
|
opacity: pressed ? 0.85 : 1
|
|
5736
5830
|
},
|
|
5737
5831
|
children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
5738
|
-
|
|
5832
|
+
import_react_native46.Pressable,
|
|
5739
5833
|
{
|
|
5740
5834
|
onPress,
|
|
5741
5835
|
onPressIn: () => setPressed(true),
|
|
@@ -5752,10 +5846,10 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
|
5752
5846
|
}
|
|
5753
5847
|
|
|
5754
5848
|
// src/components/chat/ChatHeader.tsx
|
|
5755
|
-
var
|
|
5849
|
+
var import_react_native47 = require("react-native");
|
|
5756
5850
|
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
5757
5851
|
function ChatHeader({ left, right, center, style }) {
|
|
5758
|
-
const flattenedStyle =
|
|
5852
|
+
const flattenedStyle = import_react_native47.StyleSheet.flatten([
|
|
5759
5853
|
{
|
|
5760
5854
|
paddingTop: 0
|
|
5761
5855
|
},
|
|
@@ -5773,7 +5867,7 @@ function ChatHeader({ left, right, center, style }) {
|
|
|
5773
5867
|
}
|
|
5774
5868
|
|
|
5775
5869
|
// src/components/chat/ForkNoticeBanner.tsx
|
|
5776
|
-
var
|
|
5870
|
+
var import_react_native48 = require("react-native");
|
|
5777
5871
|
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
5778
5872
|
function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
5779
5873
|
const theme = useTheme();
|
|
@@ -5794,7 +5888,7 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
|
5794
5888
|
},
|
|
5795
5889
|
style
|
|
5796
5890
|
],
|
|
5797
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(
|
|
5891
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_react_native48.View, { style: { minWidth: 0 }, children: [
|
|
5798
5892
|
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
5799
5893
|
Text,
|
|
5800
5894
|
{
|
|
@@ -5847,32 +5941,34 @@ function ChatPanel({
|
|
|
5847
5941
|
onStartDraw,
|
|
5848
5942
|
onSend
|
|
5849
5943
|
}) {
|
|
5850
|
-
const listRef =
|
|
5851
|
-
const [nearBottom, setNearBottom] =
|
|
5852
|
-
const handleSend =
|
|
5944
|
+
const listRef = React36.useRef(null);
|
|
5945
|
+
const [nearBottom, setNearBottom] = React36.useState(true);
|
|
5946
|
+
const handleSend = React36.useCallback(
|
|
5853
5947
|
async (text, composerAttachments) => {
|
|
5854
5948
|
const all = composerAttachments ?? attachments;
|
|
5855
5949
|
await onSend(text, all.length > 0 ? all : void 0);
|
|
5856
5950
|
onClearAttachments == null ? void 0 : onClearAttachments();
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5951
|
+
if (!nearBottom) {
|
|
5952
|
+
requestAnimationFrame(() => {
|
|
5953
|
+
var _a;
|
|
5954
|
+
return (_a = listRef.current) == null ? void 0 : _a.scrollToBottom({ animated: true });
|
|
5955
|
+
});
|
|
5956
|
+
}
|
|
5861
5957
|
},
|
|
5862
|
-
[attachments, onClearAttachments, onSend]
|
|
5958
|
+
[attachments, nearBottom, onClearAttachments, onSend]
|
|
5863
5959
|
);
|
|
5864
|
-
const handleScrollToBottom =
|
|
5960
|
+
const handleScrollToBottom = React36.useCallback(() => {
|
|
5865
5961
|
var _a;
|
|
5866
5962
|
(_a = listRef.current) == null ? void 0 : _a.scrollToBottom({ animated: true });
|
|
5867
5963
|
}, []);
|
|
5868
5964
|
const header = /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
|
|
5869
5965
|
ChatHeader,
|
|
5870
5966
|
{
|
|
5871
|
-
left: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
5967
|
+
left: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native49.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5872
5968
|
/* @__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
5969
|
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
5970
|
] }),
|
|
5875
|
-
right: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
|
|
5971
|
+
right: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native49.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5876
5972
|
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
5973
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconClose, { size: 20, colorToken: "floatingContent" }) })
|
|
5878
5974
|
] }),
|
|
@@ -5888,12 +5984,12 @@ function ChatPanel({
|
|
|
5888
5984
|
) : null;
|
|
5889
5985
|
const showMessagesLoading = Boolean(loading) && messages.length === 0 || forking;
|
|
5890
5986
|
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)(
|
|
5987
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native49.View, { style: { flex: 1 }, children: [
|
|
5988
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native49.View, { children: header }),
|
|
5989
|
+
topBanner ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native49.View, { style: { paddingHorizontal: 16, paddingTop: 8 }, children: topBanner }) : null,
|
|
5990
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native49.View, { style: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 24, paddingVertical: 12 }, children: [
|
|
5991
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native49.ActivityIndicator, {}),
|
|
5992
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native49.View, { style: { height: 12 } }),
|
|
5897
5993
|
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Text, { variant: "bodyMuted", children: forking ? "Creating your copy\u2026" : "Loading messages\u2026" })
|
|
5898
5994
|
] })
|
|
5899
5995
|
] });
|
|
@@ -5917,7 +6013,10 @@ function ChatPanel({
|
|
|
5917
6013
|
}
|
|
5918
6014
|
),
|
|
5919
6015
|
composer: {
|
|
5920
|
-
|
|
6016
|
+
// Keep the input editable even when sending is disallowed (e.g. agent still working),
|
|
6017
|
+
// otherwise iOS will drop focus/keyboard and BottomSheet can get "stuck" with a keyboard-sized gap.
|
|
6018
|
+
disabled: Boolean(loading) || Boolean(forking),
|
|
6019
|
+
sendDisabled: Boolean(sendDisabled) || Boolean(loading) || Boolean(forking),
|
|
5921
6020
|
sending: Boolean(sending),
|
|
5922
6021
|
autoFocus: autoFocusComposer,
|
|
5923
6022
|
onSend: handleSend,
|
|
@@ -5931,11 +6030,11 @@ function ChatPanel({
|
|
|
5931
6030
|
}
|
|
5932
6031
|
|
|
5933
6032
|
// src/components/dialogs/ConfirmMergeRequestDialog.tsx
|
|
5934
|
-
var
|
|
5935
|
-
var
|
|
6033
|
+
var React37 = __toESM(require("react"));
|
|
6034
|
+
var import_react_native51 = require("react-native");
|
|
5936
6035
|
|
|
5937
6036
|
// src/components/primitives/Modal.tsx
|
|
5938
|
-
var
|
|
6037
|
+
var import_react_native50 = require("react-native");
|
|
5939
6038
|
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
5940
6039
|
function Modal({
|
|
5941
6040
|
visible,
|
|
@@ -5946,15 +6045,15 @@ function Modal({
|
|
|
5946
6045
|
}) {
|
|
5947
6046
|
const theme = useTheme();
|
|
5948
6047
|
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
5949
|
-
|
|
6048
|
+
import_react_native50.Modal,
|
|
5950
6049
|
{
|
|
5951
6050
|
visible,
|
|
5952
6051
|
transparent: true,
|
|
5953
6052
|
animationType: "fade",
|
|
5954
6053
|
onRequestClose,
|
|
5955
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
|
|
6054
|
+
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
6055
|
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
5957
|
-
|
|
6056
|
+
import_react_native50.Pressable,
|
|
5958
6057
|
{
|
|
5959
6058
|
accessibilityRole: "button",
|
|
5960
6059
|
onPress: dismissOnBackdropPress ? onRequestClose : void 0,
|
|
@@ -5979,14 +6078,14 @@ function ConfirmMergeRequestDialog({
|
|
|
5979
6078
|
onTestFirst
|
|
5980
6079
|
}) {
|
|
5981
6080
|
const theme = useTheme();
|
|
5982
|
-
const close =
|
|
6081
|
+
const close = React37.useCallback(() => onOpenChange(false), [onOpenChange]);
|
|
5983
6082
|
const canConfirm = Boolean(mergeRequest) && !approveDisabled;
|
|
5984
|
-
const handleConfirm =
|
|
6083
|
+
const handleConfirm = React37.useCallback(() => {
|
|
5985
6084
|
if (!mergeRequest) return;
|
|
5986
6085
|
onOpenChange(false);
|
|
5987
6086
|
void onConfirm();
|
|
5988
6087
|
}, [mergeRequest, onConfirm, onOpenChange]);
|
|
5989
|
-
const handleTestFirst =
|
|
6088
|
+
const handleTestFirst = React37.useCallback(() => {
|
|
5990
6089
|
if (!mergeRequest) return;
|
|
5991
6090
|
onOpenChange(false);
|
|
5992
6091
|
void onTestFirst(mergeRequest);
|
|
@@ -6009,7 +6108,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6009
6108
|
backgroundColor: theme.colors.background
|
|
6010
6109
|
},
|
|
6011
6110
|
children: [
|
|
6012
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6111
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.View, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6013
6112
|
Text,
|
|
6014
6113
|
{
|
|
6015
6114
|
style: {
|
|
@@ -6021,9 +6120,9 @@ function ConfirmMergeRequestDialog({
|
|
|
6021
6120
|
children: "Are you sure you want to approve this merge request?"
|
|
6022
6121
|
}
|
|
6023
6122
|
) }),
|
|
6024
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
|
|
6123
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_native51.View, { style: { marginTop: 16 }, children: [
|
|
6025
6124
|
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6026
|
-
|
|
6125
|
+
import_react_native51.View,
|
|
6027
6126
|
{
|
|
6028
6127
|
style: [
|
|
6029
6128
|
fullWidthButtonBase,
|
|
@@ -6033,7 +6132,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6033
6132
|
}
|
|
6034
6133
|
],
|
|
6035
6134
|
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6036
|
-
|
|
6135
|
+
import_react_native51.Pressable,
|
|
6037
6136
|
{
|
|
6038
6137
|
accessibilityRole: "button",
|
|
6039
6138
|
accessibilityLabel: "Approve Merge",
|
|
@@ -6045,9 +6144,9 @@ function ConfirmMergeRequestDialog({
|
|
|
6045
6144
|
)
|
|
6046
6145
|
}
|
|
6047
6146
|
),
|
|
6048
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6147
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.View, { style: { height: 8 } }),
|
|
6049
6148
|
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6050
|
-
|
|
6149
|
+
import_react_native51.View,
|
|
6051
6150
|
{
|
|
6052
6151
|
style: [
|
|
6053
6152
|
fullWidthButtonBase,
|
|
@@ -6059,7 +6158,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6059
6158
|
}
|
|
6060
6159
|
],
|
|
6061
6160
|
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6062
|
-
|
|
6161
|
+
import_react_native51.Pressable,
|
|
6063
6162
|
{
|
|
6064
6163
|
accessibilityRole: "button",
|
|
6065
6164
|
accessibilityLabel: isBuilding ? "Preparing\u2026" : "Test edits first",
|
|
@@ -6071,9 +6170,9 @@ function ConfirmMergeRequestDialog({
|
|
|
6071
6170
|
)
|
|
6072
6171
|
}
|
|
6073
6172
|
),
|
|
6074
|
-
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6173
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.View, { style: { height: 8 } }),
|
|
6075
6174
|
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6076
|
-
|
|
6175
|
+
import_react_native51.View,
|
|
6077
6176
|
{
|
|
6078
6177
|
style: [
|
|
6079
6178
|
fullWidthButtonBase,
|
|
@@ -6084,7 +6183,7 @@ function ConfirmMergeRequestDialog({
|
|
|
6084
6183
|
}
|
|
6085
6184
|
],
|
|
6086
6185
|
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
6087
|
-
|
|
6186
|
+
import_react_native51.Pressable,
|
|
6088
6187
|
{
|
|
6089
6188
|
accessibilityRole: "button",
|
|
6090
6189
|
accessibilityLabel: "Cancel",
|
|
@@ -6165,30 +6264,30 @@ function StudioOverlay({
|
|
|
6165
6264
|
onNavigateHome
|
|
6166
6265
|
}) {
|
|
6167
6266
|
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 =
|
|
6267
|
+
const { width } = (0, import_react_native52.useWindowDimensions)();
|
|
6268
|
+
const [sheetOpen, setSheetOpen] = React38.useState(false);
|
|
6269
|
+
const [activePage, setActivePage] = React38.useState("preview");
|
|
6270
|
+
const [drawing, setDrawing] = React38.useState(false);
|
|
6271
|
+
const [chatAttachments, setChatAttachments] = React38.useState([]);
|
|
6272
|
+
const [commentsAppId, setCommentsAppId] = React38.useState(null);
|
|
6273
|
+
const [commentsCount, setCommentsCount] = React38.useState(null);
|
|
6274
|
+
const [confirmMrId, setConfirmMrId] = React38.useState(null);
|
|
6275
|
+
const confirmMr = React38.useMemo(
|
|
6177
6276
|
() => confirmMrId ? incomingMergeRequests.find((m) => m.id === confirmMrId) ?? null : null,
|
|
6178
6277
|
[confirmMrId, incomingMergeRequests]
|
|
6179
6278
|
);
|
|
6180
|
-
const closeSheet =
|
|
6279
|
+
const closeSheet = React38.useCallback(() => {
|
|
6181
6280
|
setSheetOpen(false);
|
|
6182
|
-
|
|
6281
|
+
import_react_native52.Keyboard.dismiss();
|
|
6183
6282
|
}, []);
|
|
6184
|
-
const openSheet =
|
|
6185
|
-
const goToChat =
|
|
6283
|
+
const openSheet = React38.useCallback(() => setSheetOpen(true), []);
|
|
6284
|
+
const goToChat = React38.useCallback(() => {
|
|
6186
6285
|
setActivePage("chat");
|
|
6187
6286
|
openSheet();
|
|
6188
6287
|
}, [openSheet]);
|
|
6189
|
-
const backToPreview =
|
|
6190
|
-
if (
|
|
6191
|
-
|
|
6288
|
+
const backToPreview = React38.useCallback(() => {
|
|
6289
|
+
if (import_react_native52.Platform.OS !== "ios") {
|
|
6290
|
+
import_react_native52.Keyboard.dismiss();
|
|
6192
6291
|
setActivePage("preview");
|
|
6193
6292
|
return;
|
|
6194
6293
|
}
|
|
@@ -6200,15 +6299,15 @@ function StudioOverlay({
|
|
|
6200
6299
|
clearTimeout(t);
|
|
6201
6300
|
setActivePage("preview");
|
|
6202
6301
|
};
|
|
6203
|
-
const sub =
|
|
6302
|
+
const sub = import_react_native52.Keyboard.addListener("keyboardDidHide", finalize);
|
|
6204
6303
|
const t = setTimeout(finalize, 350);
|
|
6205
|
-
|
|
6304
|
+
import_react_native52.Keyboard.dismiss();
|
|
6206
6305
|
}, []);
|
|
6207
|
-
const startDraw =
|
|
6306
|
+
const startDraw = React38.useCallback(() => {
|
|
6208
6307
|
setDrawing(true);
|
|
6209
6308
|
closeSheet();
|
|
6210
6309
|
}, [closeSheet]);
|
|
6211
|
-
const handleDrawCapture =
|
|
6310
|
+
const handleDrawCapture = React38.useCallback(
|
|
6212
6311
|
(dataUrl) => {
|
|
6213
6312
|
setChatAttachments((prev) => [...prev, dataUrl]);
|
|
6214
6313
|
setDrawing(false);
|
|
@@ -6217,7 +6316,7 @@ function StudioOverlay({
|
|
|
6217
6316
|
},
|
|
6218
6317
|
[openSheet]
|
|
6219
6318
|
);
|
|
6220
|
-
const toggleSheet =
|
|
6319
|
+
const toggleSheet = React38.useCallback(async () => {
|
|
6221
6320
|
if (!sheetOpen) {
|
|
6222
6321
|
const shouldExitTest = Boolean(testingMrId) || isTesting;
|
|
6223
6322
|
if (shouldExitTest) {
|
|
@@ -6229,7 +6328,7 @@ function StudioOverlay({
|
|
|
6229
6328
|
closeSheet();
|
|
6230
6329
|
}
|
|
6231
6330
|
}, [closeSheet, isTesting, onRestoreBase, sheetOpen, testingMrId]);
|
|
6232
|
-
const handleTestMr =
|
|
6331
|
+
const handleTestMr = React38.useCallback(
|
|
6233
6332
|
async (mr) => {
|
|
6234
6333
|
if (!onTestMr) return;
|
|
6235
6334
|
await onTestMr(mr);
|
|
@@ -6301,7 +6400,7 @@ function StudioOverlay({
|
|
|
6301
6400
|
badgeCount: incomingMergeRequests.length,
|
|
6302
6401
|
onPress: toggleSheet,
|
|
6303
6402
|
isLoading: (app == null ? void 0 : app.status) === "editing",
|
|
6304
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
6403
|
+
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
6404
|
}
|
|
6306
6405
|
),
|
|
6307
6406
|
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
@@ -6347,16 +6446,16 @@ function ComergeStudio({
|
|
|
6347
6446
|
onNavigateHome,
|
|
6348
6447
|
style
|
|
6349
6448
|
}) {
|
|
6350
|
-
const [activeAppId, setActiveAppId] =
|
|
6351
|
-
const [runtimeAppId, setRuntimeAppId] =
|
|
6352
|
-
const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] =
|
|
6353
|
-
const platform =
|
|
6354
|
-
|
|
6449
|
+
const [activeAppId, setActiveAppId] = React39.useState(appId);
|
|
6450
|
+
const [runtimeAppId, setRuntimeAppId] = React39.useState(appId);
|
|
6451
|
+
const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] = React39.useState(null);
|
|
6452
|
+
const platform = React39.useMemo(() => import_react_native53.Platform.OS === "ios" ? "ios" : "android", []);
|
|
6453
|
+
React39.useEffect(() => {
|
|
6355
6454
|
setActiveAppId(appId);
|
|
6356
6455
|
setRuntimeAppId(appId);
|
|
6357
6456
|
setPendingRuntimeTargetAppId(null);
|
|
6358
6457
|
}, [appId]);
|
|
6359
|
-
const captureTargetRef =
|
|
6458
|
+
const captureTargetRef = React39.useRef(null);
|
|
6360
6459
|
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
6460
|
ComergeStudioInner,
|
|
6362
6461
|
{
|
|
@@ -6392,11 +6491,11 @@ function ComergeStudioInner({
|
|
|
6392
6491
|
const { app, loading: appLoading } = useApp(activeAppId);
|
|
6393
6492
|
const { app: runtimeAppFromHook } = useApp(runtimeAppId, { enabled: runtimeAppId !== activeAppId });
|
|
6394
6493
|
const runtimeApp = runtimeAppId === activeAppId ? app : runtimeAppFromHook;
|
|
6395
|
-
const sawEditingOnPendingTargetRef =
|
|
6396
|
-
|
|
6494
|
+
const sawEditingOnPendingTargetRef = React39.useRef(false);
|
|
6495
|
+
React39.useEffect(() => {
|
|
6397
6496
|
sawEditingOnPendingTargetRef.current = false;
|
|
6398
6497
|
}, [pendingRuntimeTargetAppId]);
|
|
6399
|
-
|
|
6498
|
+
React39.useEffect(() => {
|
|
6400
6499
|
if (!pendingRuntimeTargetAppId) return;
|
|
6401
6500
|
if (activeAppId !== pendingRuntimeTargetAppId) return;
|
|
6402
6501
|
if ((app == null ? void 0 : app.status) === "editing") {
|
|
@@ -6416,10 +6515,10 @@ function ComergeStudioInner({
|
|
|
6416
6515
|
const threadId = (app == null ? void 0 : app.threadId) ?? "";
|
|
6417
6516
|
const thread = useThreadMessages(threadId);
|
|
6418
6517
|
const mergeRequests = useMergeRequests({ appId: activeAppId });
|
|
6419
|
-
const hasOpenOutgoingMr =
|
|
6518
|
+
const hasOpenOutgoingMr = React39.useMemo(() => {
|
|
6420
6519
|
return mergeRequests.lists.outgoing.some((mr) => mr.status === "open");
|
|
6421
6520
|
}, [mergeRequests.lists.outgoing]);
|
|
6422
|
-
const incomingReviewMrs =
|
|
6521
|
+
const incomingReviewMrs = React39.useMemo(() => {
|
|
6423
6522
|
if (!userId) return mergeRequests.lists.incoming;
|
|
6424
6523
|
return mergeRequests.lists.incoming.filter((mr) => mr.createdBy !== userId);
|
|
6425
6524
|
}, [mergeRequests.lists.incoming, userId]);
|
|
@@ -6441,16 +6540,16 @@ function ComergeStudioInner({
|
|
|
6441
6540
|
uploadAttachments: uploader.uploadBase64Images
|
|
6442
6541
|
});
|
|
6443
6542
|
const chatSendDisabled = hasNoOutcomeAfterLastHuman(thread.raw);
|
|
6444
|
-
const [processingMrId, setProcessingMrId] =
|
|
6445
|
-
const [testingMrId, setTestingMrId] =
|
|
6446
|
-
const chatShowTypingIndicator =
|
|
6543
|
+
const [processingMrId, setProcessingMrId] = React39.useState(null);
|
|
6544
|
+
const [testingMrId, setTestingMrId] = React39.useState(null);
|
|
6545
|
+
const chatShowTypingIndicator = React39.useMemo(() => {
|
|
6447
6546
|
var _a;
|
|
6448
6547
|
if (!thread.raw || thread.raw.length === 0) return false;
|
|
6449
6548
|
const last = thread.raw[thread.raw.length - 1];
|
|
6450
6549
|
const payloadType = typeof ((_a = last.payload) == null ? void 0 : _a.type) === "string" ? String(last.payload.type) : void 0;
|
|
6451
6550
|
return payloadType !== "outcome";
|
|
6452
6551
|
}, [thread.raw]);
|
|
6453
|
-
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
6552
|
+
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
6553
|
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(RuntimeRenderer, { appKey, bundlePath: bundle.bundlePath, renderToken: bundle.renderToken }),
|
|
6455
6554
|
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
6456
6555
|
StudioOverlay,
|