@opengeni/react-native 4.2.1-canary.39642758903001 → 4.3.1
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/android/build.gradle +15 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/dev/opengeni/textselection/OpenGeniTextSelectionModule.kt +274 -0
- package/dist/{chunk-D3MFBDVR.js → chunk-2RNMGRTB.js} +3 -3
- package/dist/{chunk-D3MFBDVR.js.map → chunk-2RNMGRTB.js.map} +1 -1
- package/dist/{chunk-2W74OY6I.js → chunk-FHPMRXIG.js} +16 -2
- package/dist/chunk-FHPMRXIG.js.map +1 -0
- package/dist/{chunk-YTT4WSJZ.js → chunk-QFV5DISV.js} +3 -3
- package/dist/{chunk-YTT4WSJZ.js.map → chunk-QFV5DISV.js.map} +1 -1
- package/dist/{chunk-U5L2CUMJ.js → chunk-ZZNZBZWV.js} +3 -3
- package/dist/{chunk-U5L2CUMJ.js.map → chunk-ZZNZBZWV.js.map} +1 -1
- package/dist/index.js +2 -2
- package/dist/timeline/annotations.d.ts +81 -0
- package/dist/timeline/icon-nodes.generated.d.ts +5 -0
- package/dist/timeline/index.d.ts +2 -0
- package/dist/timeline/index.js +1186 -197
- package/dist/timeline/index.js.map +1 -1
- package/dist/timeline/markdown.js +5 -2
- package/dist/timeline/markdown.js.map +1 -1
- package/dist/timeline/message-timeline.d.ts +20 -2
- package/dist/timeline/previews.js +2 -2
- package/dist/timeline/queue-dock.d.ts +4 -1
- package/dist/timeline/text-selection.d.ts +44 -0
- package/expo-module.config.json +5 -2
- package/ios/OpenGeniTextSelectionModule.swift +560 -0
- package/package.json +6 -4
- package/src/timeline/activity.tsx +24 -15
- package/src/timeline/annotations.tsx +877 -0
- package/src/timeline/icon-nodes.generated.ts +14 -0
- package/src/timeline/index.ts +2 -0
- package/src/timeline/markdown.tsx +7 -0
- package/src/timeline/message-timeline.tsx +340 -174
- package/src/timeline/queue-dock.tsx +36 -0
- package/src/timeline/session-screen.tsx +122 -4
- package/src/timeline/sheet.tsx +3 -2
- package/src/timeline/text-selection.ts +115 -0
- package/dist/chunk-2W74OY6I.js.map +0 -1
package/dist/timeline/index.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import { defaultSecretFieldMessages, ThinkingOrb, humanInputAnswerLines, isSecretQuestion, initialSecretDraft, secretSubmission, secretInputTraits, secretUsernameTraits, SECRET_SAVE_TO_OPTIONS, secretPatternMismatch } from '../chunk-
|
|
2
|
-
import { ActivityDisclosure, useNativeTimelineMessages, useReleaseFollow, ShimmerText,
|
|
3
|
-
export { ActivityDisclosure, BodyNote, Chip, NativeTimelineMessagesProvider, PayloadBlock, PulseDot, ShimmerText, TermBlock, defaultNativeTimelineMessages, useNativeTimelineMessages, withAlpha } from '../chunk-
|
|
4
|
-
import { NativeImageViewer } from '../chunk-
|
|
5
|
-
export { NativeImageViewer } from '../chunk-
|
|
1
|
+
import { defaultSecretFieldMessages, ThinkingOrb, humanInputAnswerLines, isSecretQuestion, initialSecretDraft, secretSubmission, secretInputTraits, secretUsernameTraits, SECRET_SAVE_TO_OPTIONS, secretPatternMismatch } from '../chunk-2RNMGRTB.js';
|
|
2
|
+
import { ActivityDisclosure, useNativeTimelineMessages, useReleaseFollow, ShimmerText, withAlpha, ReleaseFollowProvider, blendOver, NativeTimelineMessagesProvider, ROW_MIN_HEIGHT, PulseDot, BodyNote, PayloadBlock, TermBlock, Chip, RunningPreview } from '../chunk-QFV5DISV.js';
|
|
3
|
+
export { ActivityDisclosure, BodyNote, Chip, NativeTimelineMessagesProvider, PayloadBlock, PulseDot, ShimmerText, TermBlock, defaultNativeTimelineMessages, useNativeTimelineMessages, withAlpha } from '../chunk-QFV5DISV.js';
|
|
4
|
+
import { NativeImageViewer } from '../chunk-ZZNZBZWV.js';
|
|
5
|
+
export { NativeImageViewer } from '../chunk-ZZNZBZWV.js';
|
|
6
6
|
import { useOpenNativeLink } from '../chunk-2WJTBHO6.js';
|
|
7
7
|
import '../chunk-7ZDF5VGA.js';
|
|
8
|
-
import { useNativeTimelineTheme, fontStyle, Icon } from '../chunk-
|
|
9
|
-
export { Icon, NativeTimelineThemeProvider, createNativeTimelineTheme, fontStyle, useNativeTimelineTheme, webColorsDark, webColorsLight } from '../chunk-
|
|
8
|
+
import { useNativeTimelineTheme, fontStyle, Icon } from '../chunk-FHPMRXIG.js';
|
|
9
|
+
export { Icon, NativeTimelineThemeProvider, createNativeTimelineTheme, fontStyle, useNativeTimelineTheme, webColorsDark, webColorsLight } from '../chunk-FHPMRXIG.js';
|
|
10
10
|
import { buildTimeline, groupTimeline, conversationTimeline } from '@opengeni/react/session';
|
|
11
|
-
import { defaultHumanInputFormMessages, createTurnSummaryContext, resolveTurnSummaryFacets, selectTurnSummaryFacets, formatElapsed, turnSummaryFallbackLabel, rollingActivityItem, toolDisplayName, questionNavTarget, timelineGroupIndexAtSequence, QUESTION_NAV_MARGIN_PX, flattenActivityItems, timelineGroupContainsPresentedImage, durationBetween, isPreparingWork, readableWorkStatus, readableWorkShowsPreview, readableWorkDefaultOpen, compactedLandmarkCount, SESSION_STATUS_PRESENTATION, formatRelativeTime, recordedWaitSummaryText, noticeTone, noticeDisplayText, isActionableHumanInputRequest, humanInputHeading, initialDrafts, emptyDraft, SESSION_STATUS_BADGE, workerRowTitle, startupDuration, STARTUP_WAIT_TITLES, startupPhaseTitle, sandboxRowTitle, toolRowPresentation, presentsToolOutputPreview, GENIE_WAITING_PHRASES, GENIE_PREPARING_PHRASES, answersFromDrafts, notificationPlainText, pathDirname, pathBasename, formatClockTime, parseNotificationText } from '@opengeni/react/timeline-model';
|
|
11
|
+
import { defaultHumanInputFormMessages, createTurnSummaryContext, resolveTurnSummaryFacets, selectTurnSummaryFacets, formatElapsed, turnSummaryFallbackLabel, rollingActivityItem, toolDisplayName, annotationHasNote, annotationDisplayOrdinal, ANNOTATION_MAX_NOTE_LENGTH, questionNavTarget, timelineGroupIndexAtSequence, QUESTION_NAV_MARGIN_PX, flattenActivityItems, timelineGroupContainsPresentedImage, durationBetween, isPreparingWork, readableWorkStatus, readableWorkShowsPreview, readableWorkDefaultOpen, compactedLandmarkCount, SESSION_STATUS_PRESENTATION, formatRelativeTime, recordedWaitSummaryText, noticeTone, noticeDisplayText, isActionableHumanInputRequest, humanInputHeading, initialDrafts, emptyDraft, SESSION_STATUS_BADGE, workerRowTitle, startupDuration, STARTUP_WAIT_TITLES, startupPhaseTitle, sandboxRowTitle, toolRowPresentation, presentsToolOutputPreview, GENIE_WAITING_PHRASES, GENIE_PREPARING_PHRASES, truncateAnnotationQuote, annotationNoteNeedsDisclosure, annotationFromSelection, answersFromDrafts, notificationPlainText, pathDirname, pathBasename, formatClockTime, parseNotificationText } from '@opengeni/react/timeline-model';
|
|
12
12
|
import { createContext, useContext, useRef, useState, useEffect, useMemo, useCallback, useId } from 'react';
|
|
13
|
-
import { Platform, Text, View, Pressable,
|
|
14
|
-
import Animated, { FadeIn, FadeOut, FadeOutUp, FadeInDown, useAnimatedKeyboard, useAnimatedStyle, useReducedMotion, useSharedValue, cancelAnimation, withRepeat, withTiming, Easing } from 'react-native-reanimated';
|
|
13
|
+
import { Platform, Text, View, Pressable, useWindowDimensions, Animated as Animated$1, AccessibilityInfo, Easing, PanResponder, Modal, KeyboardAvoidingView, ScrollView, TextInput, Keyboard, ActivityIndicator, Image, Alert, AppState, ActionSheetIOS, Linking } from 'react-native';
|
|
14
|
+
import Animated, { FadeIn, FadeOut, FadeOutUp, FadeInDown, useAnimatedKeyboard, useAnimatedStyle, useReducedMotion, useSharedValue, cancelAnimation, withRepeat, withTiming, Easing as Easing$1 } from 'react-native-reanimated';
|
|
15
15
|
import { createOpenGeniText, useOpenGeniText, SingleSendWording } from '@opengeni/react/messages';
|
|
16
16
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
17
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
17
18
|
import { defaultChatComposerMessages } from '@opengeni/react/composer-messages';
|
|
18
19
|
import { isLiquidGlassAvailable, GlassView } from 'expo-glass-effect';
|
|
19
20
|
import { loadSessionFeedback, turnRatingsFromFeedback, feedbackSentimentLabel, feedbackDialogCopy, feedbackSubmission } from '@opengeni/react/session-feedback-model';
|
|
@@ -23,9 +24,60 @@ import { modelMarkVendor, MODEL_MARK_PATHS } from '@opengeni/react/model-mark-pa
|
|
|
23
24
|
import { projectClientModelRows, labelReasoningEffort } from '@opengeni/react/model-policy';
|
|
24
25
|
import { sessionDisplayTitle, recentSessionStatus, recentSessionModelPresentation, sessionRepoLabel, relativeTimeLabel, sessionRenameSeed, SESSION_TITLE_MAX_LENGTH, resolveRenameSubmission } from '@opengeni/react/session-list-model';
|
|
25
26
|
import Svg, { Path } from 'react-native-svg';
|
|
26
|
-
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
27
27
|
import { modelPickerMenuView, groupPresentationFor, compactEffortLabel, modelPickerChoice } from '@opengeni/react/model-picker-model';
|
|
28
28
|
|
|
29
|
+
var ANNOTATION_SOURCE_TEST_ID_PREFIX = "og-annotation-source:";
|
|
30
|
+
function annotationSourceTestId(sourceKey) {
|
|
31
|
+
return `${ANNOTATION_SOURCE_TEST_ID_PREFIX}${sourceKey ?? ""}`;
|
|
32
|
+
}
|
|
33
|
+
function textSelectionModule() {
|
|
34
|
+
if (Platform.OS !== "ios" && Platform.OS !== "android") return null;
|
|
35
|
+
const registry = globalThis.expo?.modules;
|
|
36
|
+
const module = registry?.OpenGeniTextSelection;
|
|
37
|
+
return module && typeof module.addListener === "function" ? module : null;
|
|
38
|
+
}
|
|
39
|
+
async function measureQuoteAnchors(sourceKey, queries) {
|
|
40
|
+
const module = textSelectionModule();
|
|
41
|
+
if (!module?.quoteAnchors || queries.length === 0) return queries.map(() => null);
|
|
42
|
+
try {
|
|
43
|
+
const anchors = await module.quoteAnchors(sourceKey, queries);
|
|
44
|
+
return queries.map((_, index) => {
|
|
45
|
+
const anchor = anchors[index];
|
|
46
|
+
if (typeof anchor?.x !== "number" || typeof anchor.top !== "number") return null;
|
|
47
|
+
const flat = anchor.rects ?? [];
|
|
48
|
+
const boxes = [];
|
|
49
|
+
for (let at = 0; at + 3 < flat.length; at += 4) {
|
|
50
|
+
boxes.push({ x: flat[at], y: flat[at + 1], width: flat[at + 2], height: flat[at + 3] });
|
|
51
|
+
}
|
|
52
|
+
return { x: anchor.x, top: anchor.top, boxes };
|
|
53
|
+
});
|
|
54
|
+
} catch {
|
|
55
|
+
return queries.map(() => null);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function useNativeTextAnnotation(sources, onAnnotate) {
|
|
59
|
+
const t = useOpenGeniText();
|
|
60
|
+
const latest = useRef({ sources, onAnnotate });
|
|
61
|
+
latest.current = { sources, onAnnotate };
|
|
62
|
+
const enabled = Boolean(onAnnotate);
|
|
63
|
+
const title = t("timelineAnnotationSelection.addNote");
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
const module = textSelectionModule();
|
|
66
|
+
if (!module || !enabled) return;
|
|
67
|
+
module.setAnnotateTitle(title);
|
|
68
|
+
const subscription = module.addListener("onAnnotate", (event) => {
|
|
69
|
+
const source = latest.current.sources.get(event.sourceKey);
|
|
70
|
+
if (!source) return;
|
|
71
|
+
const annotation = annotationFromSelection(source, {
|
|
72
|
+
text: event.quote,
|
|
73
|
+
textBefore: event.before,
|
|
74
|
+
textAfter: event.after
|
|
75
|
+
});
|
|
76
|
+
if (annotation) latest.current.onAnnotate?.(annotation);
|
|
77
|
+
});
|
|
78
|
+
return () => subscription.remove();
|
|
79
|
+
}, [enabled, title]);
|
|
80
|
+
}
|
|
29
81
|
var ActivityOptionsContext = createContext({});
|
|
30
82
|
var NativeActivityOptionsProvider = ActivityOptionsContext.Provider;
|
|
31
83
|
function useNativeActivityOptions() {
|
|
@@ -400,9 +452,10 @@ function ReasoningRow({ item, compact }) {
|
|
|
400
452
|
),
|
|
401
453
|
accessibilityLabel: item.streaming ? m.thinking : m.thought,
|
|
402
454
|
preview: plain || void 0,
|
|
403
|
-
children: options.renderMarkdown ? options.renderMarkdown(item.text, { tone: "muted", streaming: item.streaming }) : /* @__PURE__ */ jsx(
|
|
455
|
+
children: /* @__PURE__ */ jsx(View, { testID: annotationSourceTestId(void 0), collapsable: false, children: options.renderMarkdown ? options.renderMarkdown(item.text, { tone: "muted", streaming: item.streaming }) : /* @__PURE__ */ jsx(
|
|
404
456
|
Text,
|
|
405
457
|
{
|
|
458
|
+
selectable: true,
|
|
406
459
|
style: {
|
|
407
460
|
...fontStyle(theme),
|
|
408
461
|
fontSize: theme.size.base,
|
|
@@ -411,7 +464,7 @@ function ReasoningRow({ item, compact }) {
|
|
|
411
464
|
},
|
|
412
465
|
children: item.text
|
|
413
466
|
}
|
|
414
|
-
)
|
|
467
|
+
) })
|
|
415
468
|
}
|
|
416
469
|
);
|
|
417
470
|
}
|
|
@@ -578,18 +631,27 @@ function ActivityNoteRow({ item }) {
|
|
|
578
631
|
children: [
|
|
579
632
|
/* @__PURE__ */ jsx(View, { style: { width: 14 } }),
|
|
580
633
|
/* @__PURE__ */ jsx(View, { style: { marginTop: 4 }, children: /* @__PURE__ */ jsx(Icon, { name: "message-square-text", size: 14, color: theme.colors["fg-subtle"] }) }),
|
|
581
|
-
/* @__PURE__ */ jsx(
|
|
582
|
-
|
|
634
|
+
/* @__PURE__ */ jsx(
|
|
635
|
+
View,
|
|
583
636
|
{
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
637
|
+
testID: annotationSourceTestId(item.annotationSource?.eventId),
|
|
638
|
+
collapsable: false,
|
|
639
|
+
style: { flex: 1, minWidth: 0 },
|
|
640
|
+
children: options.renderMarkdown ? options.renderMarkdown(item.text, { tone: "muted", streaming: item.streaming }) : /* @__PURE__ */ jsx(
|
|
641
|
+
Text,
|
|
642
|
+
{
|
|
643
|
+
selectable: true,
|
|
644
|
+
style: {
|
|
645
|
+
...fontStyle(theme),
|
|
646
|
+
fontSize: theme.size.sm,
|
|
647
|
+
lineHeight: 20,
|
|
648
|
+
color: theme.colors["fg-muted"]
|
|
649
|
+
},
|
|
650
|
+
children: item.text
|
|
651
|
+
}
|
|
652
|
+
)
|
|
591
653
|
}
|
|
592
|
-
)
|
|
654
|
+
)
|
|
593
655
|
]
|
|
594
656
|
}
|
|
595
657
|
);
|
|
@@ -1170,9 +1232,828 @@ function liveFoldShift(liveNotes, workId, open, heights, rowGap) {
|
|
|
1170
1232
|
}, 0);
|
|
1171
1233
|
return height === 0 ? 0 : open ? -height : height;
|
|
1172
1234
|
}
|
|
1235
|
+
function BottomSheet(props) {
|
|
1236
|
+
const t = useOpenGeniText();
|
|
1237
|
+
const theme = useNativeTimelineTheme();
|
|
1238
|
+
const c = theme.colors;
|
|
1239
|
+
const insets = useSafeAreaInsets();
|
|
1240
|
+
const { height } = useWindowDimensions();
|
|
1241
|
+
const [mounted, setMounted] = useState(props.open);
|
|
1242
|
+
const progress = useRef(new Animated$1.Value(0)).current;
|
|
1243
|
+
const drag = useRef(new Animated$1.Value(0)).current;
|
|
1244
|
+
const onClose = useRef(props.onClose);
|
|
1245
|
+
onClose.current = props.onClose;
|
|
1246
|
+
useEffect(() => {
|
|
1247
|
+
let cancelled = false;
|
|
1248
|
+
if (props.open) {
|
|
1249
|
+
setMounted(true);
|
|
1250
|
+
drag.setValue(0);
|
|
1251
|
+
void AccessibilityInfo.isReduceMotionEnabled().then((reduce) => {
|
|
1252
|
+
if (cancelled) return;
|
|
1253
|
+
Animated$1.timing(progress, {
|
|
1254
|
+
toValue: 1,
|
|
1255
|
+
duration: reduce ? 0 : 260,
|
|
1256
|
+
easing: Easing.bezier(0.22, 1, 0.36, 1),
|
|
1257
|
+
useNativeDriver: true
|
|
1258
|
+
}).start();
|
|
1259
|
+
});
|
|
1260
|
+
} else if (mounted) {
|
|
1261
|
+
Animated$1.timing(progress, {
|
|
1262
|
+
toValue: 0,
|
|
1263
|
+
duration: 200,
|
|
1264
|
+
easing: Easing.in(Easing.quad),
|
|
1265
|
+
useNativeDriver: true
|
|
1266
|
+
}).start(({ finished }) => {
|
|
1267
|
+
if (finished && !cancelled) setMounted(false);
|
|
1268
|
+
});
|
|
1269
|
+
}
|
|
1270
|
+
return () => {
|
|
1271
|
+
cancelled = true;
|
|
1272
|
+
};
|
|
1273
|
+
}, [drag, mounted, progress, props.open]);
|
|
1274
|
+
const pan = useRef(
|
|
1275
|
+
PanResponder.create({
|
|
1276
|
+
onMoveShouldSetPanResponder: (_event, gesture) => gesture.dy > 6 && Math.abs(gesture.dy) > Math.abs(gesture.dx),
|
|
1277
|
+
onPanResponderMove: (_event, gesture) => drag.setValue(Math.max(0, gesture.dy)),
|
|
1278
|
+
onPanResponderRelease: (_event, gesture) => {
|
|
1279
|
+
if (gesture.dy > 90 || gesture.vy > 0.9) onClose.current();
|
|
1280
|
+
else Animated$1.spring(drag, { toValue: 0, useNativeDriver: true, bounciness: 0 }).start();
|
|
1281
|
+
},
|
|
1282
|
+
onPanResponderTerminate: () => Animated$1.spring(drag, { toValue: 0, useNativeDriver: true, bounciness: 0 }).start()
|
|
1283
|
+
})
|
|
1284
|
+
).current;
|
|
1285
|
+
if (!mounted) return null;
|
|
1286
|
+
const translateY = Animated$1.add(
|
|
1287
|
+
progress.interpolate({ inputRange: [0, 1], outputRange: [height, 0] }),
|
|
1288
|
+
drag
|
|
1289
|
+
);
|
|
1290
|
+
return /* @__PURE__ */ jsx(
|
|
1291
|
+
Modal,
|
|
1292
|
+
{
|
|
1293
|
+
visible: true,
|
|
1294
|
+
transparent: true,
|
|
1295
|
+
animationType: "none",
|
|
1296
|
+
statusBarTranslucent: true,
|
|
1297
|
+
onRequestClose: props.onClose,
|
|
1298
|
+
children: /* @__PURE__ */ jsxs(
|
|
1299
|
+
KeyboardAvoidingView,
|
|
1300
|
+
{
|
|
1301
|
+
behavior: "padding",
|
|
1302
|
+
style: { flex: 1, justifyContent: "flex-end" },
|
|
1303
|
+
children: [
|
|
1304
|
+
/* @__PURE__ */ jsx(
|
|
1305
|
+
Animated$1.View,
|
|
1306
|
+
{
|
|
1307
|
+
style: {
|
|
1308
|
+
position: "absolute",
|
|
1309
|
+
top: 0,
|
|
1310
|
+
right: 0,
|
|
1311
|
+
bottom: 0,
|
|
1312
|
+
left: 0,
|
|
1313
|
+
backgroundColor: "rgba(0, 0, 0, 0.4)",
|
|
1314
|
+
opacity: progress
|
|
1315
|
+
},
|
|
1316
|
+
children: /* @__PURE__ */ jsx(
|
|
1317
|
+
Pressable,
|
|
1318
|
+
{
|
|
1319
|
+
style: { flex: 1 },
|
|
1320
|
+
onPress: props.onClose,
|
|
1321
|
+
accessibilityRole: "button",
|
|
1322
|
+
accessibilityLabel: t("native.timeline.sheet.close")
|
|
1323
|
+
}
|
|
1324
|
+
)
|
|
1325
|
+
}
|
|
1326
|
+
),
|
|
1327
|
+
/* @__PURE__ */ jsxs(
|
|
1328
|
+
Animated$1.View,
|
|
1329
|
+
{
|
|
1330
|
+
accessibilityViewIsModal: true,
|
|
1331
|
+
accessibilityLabel: props.accessibilityLabel,
|
|
1332
|
+
style: {
|
|
1333
|
+
maxHeight: height * (props.maxHeightRatio ?? 0.85),
|
|
1334
|
+
backgroundColor: c.bg,
|
|
1335
|
+
borderTopLeftRadius: 16,
|
|
1336
|
+
borderTopRightRadius: 16,
|
|
1337
|
+
paddingBottom: Math.max(insets.bottom, 12),
|
|
1338
|
+
transform: [{ translateY }],
|
|
1339
|
+
shadowColor: "#000",
|
|
1340
|
+
shadowOpacity: 0.12,
|
|
1341
|
+
shadowRadius: 16,
|
|
1342
|
+
shadowOffset: { width: 0, height: -2 },
|
|
1343
|
+
elevation: 16
|
|
1344
|
+
},
|
|
1345
|
+
children: [
|
|
1346
|
+
/* @__PURE__ */ jsx(
|
|
1347
|
+
View,
|
|
1348
|
+
{
|
|
1349
|
+
...pan.panHandlers,
|
|
1350
|
+
style: { alignItems: "center", paddingTop: 8, paddingBottom: 4 },
|
|
1351
|
+
children: /* @__PURE__ */ jsx(
|
|
1352
|
+
View,
|
|
1353
|
+
{
|
|
1354
|
+
style: {
|
|
1355
|
+
width: 36,
|
|
1356
|
+
height: 5,
|
|
1357
|
+
borderRadius: 3,
|
|
1358
|
+
backgroundColor: c["border-strong"] ?? c.border
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
)
|
|
1362
|
+
}
|
|
1363
|
+
),
|
|
1364
|
+
props.children
|
|
1365
|
+
]
|
|
1366
|
+
}
|
|
1367
|
+
)
|
|
1368
|
+
]
|
|
1369
|
+
}
|
|
1370
|
+
)
|
|
1371
|
+
}
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1374
|
+
function annotationQuoteQuery(annotation) {
|
|
1375
|
+
return {
|
|
1376
|
+
quote: annotation.quote,
|
|
1377
|
+
before: annotation.source.contextBefore,
|
|
1378
|
+
after: annotation.source.contextAfter
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
var AnnotationSourcesContext = createContext(null);
|
|
1382
|
+
function draftMarkersBySource(annotations) {
|
|
1383
|
+
const markers = /* @__PURE__ */ new Map();
|
|
1384
|
+
(annotations ?? []).forEach((annotation, index) => {
|
|
1385
|
+
const list = markers.get(annotation.source.eventId) ?? [];
|
|
1386
|
+
list.push({
|
|
1387
|
+
id: annotation.id,
|
|
1388
|
+
ordinal: index + 1,
|
|
1389
|
+
incomplete: !annotationHasNote(annotation.note),
|
|
1390
|
+
quote: annotation.quote,
|
|
1391
|
+
before: annotation.source.contextBefore,
|
|
1392
|
+
after: annotation.source.contextAfter
|
|
1393
|
+
});
|
|
1394
|
+
markers.set(annotation.source.eventId, list);
|
|
1395
|
+
});
|
|
1396
|
+
return markers;
|
|
1397
|
+
}
|
|
1398
|
+
function quotePreview(quote) {
|
|
1399
|
+
const trimmed = quote.trim();
|
|
1400
|
+
return trimmed.includes("\n") ? trimmed : trimmed.replace(/\s+/g, " ");
|
|
1401
|
+
}
|
|
1402
|
+
function AnnotationSourceView({
|
|
1403
|
+
sourceKey,
|
|
1404
|
+
children,
|
|
1405
|
+
style
|
|
1406
|
+
}) {
|
|
1407
|
+
const theme = useNativeTimelineTheme();
|
|
1408
|
+
const sources = useContext(AnnotationSourcesContext);
|
|
1409
|
+
const glow = useRef(new Animated$1.Value(0)).current;
|
|
1410
|
+
const flash = sourceKey && sources?.flash?.sourceKey === sourceKey ? sources.flash : null;
|
|
1411
|
+
const [flashBoxes, setFlashBoxes] = useState(null);
|
|
1412
|
+
useEffect(() => {
|
|
1413
|
+
if (!flash || !sourceKey) return;
|
|
1414
|
+
let cancelled = false;
|
|
1415
|
+
const start = (boxes) => {
|
|
1416
|
+
if (cancelled) return;
|
|
1417
|
+
setFlashBoxes(boxes);
|
|
1418
|
+
glow.setValue(1);
|
|
1419
|
+
Animated$1.timing(glow, {
|
|
1420
|
+
toValue: 0,
|
|
1421
|
+
duration: boxes ? 1800 : 1400,
|
|
1422
|
+
delay: 300,
|
|
1423
|
+
easing: Easing.out(Easing.quad),
|
|
1424
|
+
useNativeDriver: false
|
|
1425
|
+
}).start();
|
|
1426
|
+
};
|
|
1427
|
+
if (!flash.quote) start(null);
|
|
1428
|
+
else
|
|
1429
|
+
void measureQuoteAnchors(sourceKey, [flash.quote]).then(
|
|
1430
|
+
([anchor]) => start(anchor?.boxes.length ? anchor.boxes : null)
|
|
1431
|
+
);
|
|
1432
|
+
return () => {
|
|
1433
|
+
cancelled = true;
|
|
1434
|
+
};
|
|
1435
|
+
}, [flash, glow, sourceKey]);
|
|
1436
|
+
const register = sources?.register;
|
|
1437
|
+
const markers = sourceKey ? sources?.drafts.get(sourceKey) : void 0;
|
|
1438
|
+
const [anchors, setAnchors] = useState(null);
|
|
1439
|
+
const [size, setSize] = useState({ width: 0, height: 0 });
|
|
1440
|
+
const measure = useCallback(() => {
|
|
1441
|
+
if (!sourceKey || !markers?.length) return;
|
|
1442
|
+
const queries = markers.map(({ quote, before, after }) => ({ quote, before, after }));
|
|
1443
|
+
void measureQuoteAnchors(sourceKey, queries).then((at) => setAnchors({ markers, at }));
|
|
1444
|
+
}, [markers, sourceKey]);
|
|
1445
|
+
useEffect(() => {
|
|
1446
|
+
if (!markers?.length) {
|
|
1447
|
+
setAnchors(null);
|
|
1448
|
+
return;
|
|
1449
|
+
}
|
|
1450
|
+
const frame = requestAnimationFrame(measure);
|
|
1451
|
+
return () => cancelAnimationFrame(frame);
|
|
1452
|
+
}, [markers, measure, size.width, size.height]);
|
|
1453
|
+
return /* @__PURE__ */ jsxs(
|
|
1454
|
+
Animated$1.View,
|
|
1455
|
+
{
|
|
1456
|
+
ref: (node) => {
|
|
1457
|
+
if (sourceKey && register) register(sourceKey, node);
|
|
1458
|
+
},
|
|
1459
|
+
testID: annotationSourceTestId(sourceKey),
|
|
1460
|
+
collapsable: false,
|
|
1461
|
+
onLayout: (event) => {
|
|
1462
|
+
const { width, height } = event.nativeEvent.layout;
|
|
1463
|
+
setSize(
|
|
1464
|
+
(current) => current.width === width && current.height === height ? current : { width, height }
|
|
1465
|
+
);
|
|
1466
|
+
},
|
|
1467
|
+
style: [
|
|
1468
|
+
style,
|
|
1469
|
+
{
|
|
1470
|
+
borderRadius: theme.radius.md,
|
|
1471
|
+
backgroundColor: flashBoxes ? "transparent" : glow.interpolate({
|
|
1472
|
+
inputRange: [0, 1],
|
|
1473
|
+
outputRange: [withAlpha(theme.colors.fg, 0), withAlpha(theme.colors.fg, 0.08)]
|
|
1474
|
+
})
|
|
1475
|
+
}
|
|
1476
|
+
],
|
|
1477
|
+
children: [
|
|
1478
|
+
flashBoxes ? /* @__PURE__ */ jsx(QuoteFlash, { boxes: flashBoxes, glow }) : null,
|
|
1479
|
+
markers?.length && anchors?.markers === markers ? /* @__PURE__ */ jsx(QuoteHighlights, { anchors: anchors.at }) : null,
|
|
1480
|
+
children,
|
|
1481
|
+
markers?.length && anchors?.markers === markers ? /* @__PURE__ */ jsx(
|
|
1482
|
+
QuoteBadges,
|
|
1483
|
+
{
|
|
1484
|
+
markers,
|
|
1485
|
+
anchors: anchors.at,
|
|
1486
|
+
size,
|
|
1487
|
+
onSelect: sources?.onSelectDraft
|
|
1488
|
+
}
|
|
1489
|
+
) : null
|
|
1490
|
+
]
|
|
1491
|
+
}
|
|
1492
|
+
);
|
|
1493
|
+
}
|
|
1494
|
+
var BADGE_SIZE = 15;
|
|
1495
|
+
function boxKey(box) {
|
|
1496
|
+
return `${Math.round(box.x)}:${Math.round(box.y)}:${Math.round(box.width)}`;
|
|
1497
|
+
}
|
|
1498
|
+
function QuoteFlash({ boxes, glow }) {
|
|
1499
|
+
const theme = useNativeTimelineTheme();
|
|
1500
|
+
const tint = withAlpha(theme.colors.accent, theme.scheme === "dark" ? 0.45 : 0.28);
|
|
1501
|
+
return /* @__PURE__ */ jsx(Fragment, { children: boxes.map((box) => /* @__PURE__ */ jsx(
|
|
1502
|
+
Animated$1.View,
|
|
1503
|
+
{
|
|
1504
|
+
pointerEvents: "none",
|
|
1505
|
+
style: {
|
|
1506
|
+
position: "absolute",
|
|
1507
|
+
left: box.x - 3,
|
|
1508
|
+
top: box.y - 2,
|
|
1509
|
+
width: box.width + 6,
|
|
1510
|
+
height: box.height + 4,
|
|
1511
|
+
borderRadius: 5,
|
|
1512
|
+
backgroundColor: tint,
|
|
1513
|
+
opacity: glow
|
|
1514
|
+
}
|
|
1515
|
+
},
|
|
1516
|
+
boxKey(box)
|
|
1517
|
+
)) });
|
|
1518
|
+
}
|
|
1519
|
+
function QuoteHighlights({ anchors }) {
|
|
1520
|
+
const theme = useNativeTimelineTheme();
|
|
1521
|
+
const dark = theme.scheme === "dark";
|
|
1522
|
+
const tint = withAlpha(theme.colors.accent, dark ? 0.16 : 0.08);
|
|
1523
|
+
const rule = withAlpha(theme.colors.accent, dark ? 0.7 : 0.55);
|
|
1524
|
+
return /* @__PURE__ */ jsx(Fragment, { children: anchors.flatMap(
|
|
1525
|
+
(anchor) => (anchor?.boxes ?? []).map((box) => /* @__PURE__ */ jsx(
|
|
1526
|
+
View,
|
|
1527
|
+
{
|
|
1528
|
+
pointerEvents: "none",
|
|
1529
|
+
style: {
|
|
1530
|
+
position: "absolute",
|
|
1531
|
+
left: box.x - 2,
|
|
1532
|
+
top: box.y - 1,
|
|
1533
|
+
width: box.width + 4,
|
|
1534
|
+
height: box.height + 2,
|
|
1535
|
+
borderTopLeftRadius: 3,
|
|
1536
|
+
borderTopRightRadius: 3,
|
|
1537
|
+
borderBottomWidth: 1.5,
|
|
1538
|
+
borderBottomColor: rule,
|
|
1539
|
+
backgroundColor: tint
|
|
1540
|
+
}
|
|
1541
|
+
},
|
|
1542
|
+
boxKey(box)
|
|
1543
|
+
))
|
|
1544
|
+
) });
|
|
1545
|
+
}
|
|
1546
|
+
function QuoteBadges({
|
|
1547
|
+
markers,
|
|
1548
|
+
anchors,
|
|
1549
|
+
size,
|
|
1550
|
+
onSelect
|
|
1551
|
+
}) {
|
|
1552
|
+
const t = useOpenGeniText();
|
|
1553
|
+
const theme = useNativeTimelineTheme();
|
|
1554
|
+
const c = theme.colors;
|
|
1555
|
+
let unplaced = 0;
|
|
1556
|
+
return /* @__PURE__ */ jsx(Fragment, { children: markers.map((marker, index) => {
|
|
1557
|
+
const anchor = anchors[index];
|
|
1558
|
+
const center = anchor ? { x: anchor.x + 2, y: anchor.top - 1 } : {
|
|
1559
|
+
x: size.width - BADGE_SIZE / 2 - unplaced++ * (BADGE_SIZE + 4),
|
|
1560
|
+
y: size.height - BADGE_SIZE / 2
|
|
1561
|
+
};
|
|
1562
|
+
const left = Math.min(Math.max(center.x - BADGE_SIZE / 2, 0), size.width - BADGE_SIZE);
|
|
1563
|
+
return /* @__PURE__ */ jsx(
|
|
1564
|
+
Pressable,
|
|
1565
|
+
{
|
|
1566
|
+
accessibilityRole: "button",
|
|
1567
|
+
accessibilityLabel: t("timelineAnnotationMarkers.annotationOrdinal", {
|
|
1568
|
+
ordinal: marker.ordinal
|
|
1569
|
+
}),
|
|
1570
|
+
hitSlop: 14,
|
|
1571
|
+
disabled: !onSelect,
|
|
1572
|
+
onPress: () => onSelect?.(marker.id),
|
|
1573
|
+
style: ({ pressed }) => ({
|
|
1574
|
+
position: "absolute",
|
|
1575
|
+
left,
|
|
1576
|
+
top: center.y - BADGE_SIZE / 2,
|
|
1577
|
+
zIndex: marker.ordinal,
|
|
1578
|
+
minWidth: BADGE_SIZE,
|
|
1579
|
+
height: BADGE_SIZE,
|
|
1580
|
+
paddingHorizontal: 2,
|
|
1581
|
+
borderRadius: BADGE_SIZE / 2,
|
|
1582
|
+
alignItems: "center",
|
|
1583
|
+
justifyContent: "center",
|
|
1584
|
+
backgroundColor: c.accent,
|
|
1585
|
+
borderWidth: marker.incomplete ? 1 : 0,
|
|
1586
|
+
borderColor: withAlpha(c["accent-fg"], 0.35),
|
|
1587
|
+
opacity: pressed ? 0.7 : 1,
|
|
1588
|
+
shadowColor: "#000",
|
|
1589
|
+
shadowOpacity: 0.12,
|
|
1590
|
+
shadowRadius: 2,
|
|
1591
|
+
shadowOffset: { width: 0, height: 1 }
|
|
1592
|
+
}),
|
|
1593
|
+
children: /* @__PURE__ */ jsx(
|
|
1594
|
+
Text,
|
|
1595
|
+
{
|
|
1596
|
+
style: {
|
|
1597
|
+
...fontStyle(theme, 600),
|
|
1598
|
+
fontSize: 10,
|
|
1599
|
+
lineHeight: 12,
|
|
1600
|
+
color: c["accent-fg"],
|
|
1601
|
+
fontVariant: ["tabular-nums"]
|
|
1602
|
+
},
|
|
1603
|
+
children: marker.ordinal
|
|
1604
|
+
}
|
|
1605
|
+
)
|
|
1606
|
+
},
|
|
1607
|
+
marker.id
|
|
1608
|
+
);
|
|
1609
|
+
}) });
|
|
1610
|
+
}
|
|
1611
|
+
function AccentRow({ children, shrink = false }) {
|
|
1612
|
+
const theme = useNativeTimelineTheme();
|
|
1613
|
+
return /* @__PURE__ */ jsxs(View, { style: { flexDirection: "row", gap: 10 }, children: [
|
|
1614
|
+
/* @__PURE__ */ jsx(
|
|
1615
|
+
View,
|
|
1616
|
+
{
|
|
1617
|
+
style: {
|
|
1618
|
+
width: 2,
|
|
1619
|
+
borderRadius: 1,
|
|
1620
|
+
backgroundColor: withAlpha(theme.colors.accent, 0.55)
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
),
|
|
1624
|
+
/* @__PURE__ */ jsx(View, { style: shrink ? { flexShrink: 1, minWidth: 0 } : { flex: 1, minWidth: 0 }, children })
|
|
1625
|
+
] });
|
|
1626
|
+
}
|
|
1627
|
+
function OrdinalLabel({ ordinal }) {
|
|
1628
|
+
const t = useOpenGeniText();
|
|
1629
|
+
const theme = useNativeTimelineTheme();
|
|
1630
|
+
return /* @__PURE__ */ jsx(
|
|
1631
|
+
Text,
|
|
1632
|
+
{
|
|
1633
|
+
style: {
|
|
1634
|
+
...fontStyle(theme, 500),
|
|
1635
|
+
fontSize: theme.size.xs,
|
|
1636
|
+
lineHeight: 16,
|
|
1637
|
+
color: theme.colors["fg-subtle"],
|
|
1638
|
+
fontVariant: ["tabular-nums"]
|
|
1639
|
+
},
|
|
1640
|
+
children: t("timelineAnnotations.annotationOrdinal", { ordinal })
|
|
1641
|
+
}
|
|
1642
|
+
);
|
|
1643
|
+
}
|
|
1644
|
+
function QuoteButton({
|
|
1645
|
+
annotation,
|
|
1646
|
+
onReveal
|
|
1647
|
+
}) {
|
|
1648
|
+
const t = useOpenGeniText();
|
|
1649
|
+
const theme = useNativeTimelineTheme();
|
|
1650
|
+
const [unavailable, setUnavailable] = useState(false);
|
|
1651
|
+
const text = /* @__PURE__ */ jsx(
|
|
1652
|
+
Text,
|
|
1653
|
+
{
|
|
1654
|
+
numberOfLines: 2,
|
|
1655
|
+
style: {
|
|
1656
|
+
...fontStyle(theme),
|
|
1657
|
+
fontSize: theme.size.sm,
|
|
1658
|
+
lineHeight: 20,
|
|
1659
|
+
color: theme.colors["fg-muted"]
|
|
1660
|
+
},
|
|
1661
|
+
children: quotePreview(annotation.quote)
|
|
1662
|
+
}
|
|
1663
|
+
);
|
|
1664
|
+
if (!onReveal) return text;
|
|
1665
|
+
return /* @__PURE__ */ jsxs(View, { children: [
|
|
1666
|
+
/* @__PURE__ */ jsx(
|
|
1667
|
+
Pressable,
|
|
1668
|
+
{
|
|
1669
|
+
accessibilityRole: "button",
|
|
1670
|
+
accessibilityLabel: t(
|
|
1671
|
+
"timelineAnnotationChrome.viewSourcelabelSourceTruncateannotationquote",
|
|
1672
|
+
{
|
|
1673
|
+
sourceLabel: annotation.source.label?.trim() || (annotation.source.kind === "user_message" ? t("timelineAnnotationShared.yourMessage") : annotation.source.kind === "assistant_message" ? t("timelineAnnotationShared.assistant") : t("timelineAnnotationShared.toolOutput")),
|
|
1674
|
+
truncateAnnotationQuote: truncateAnnotationQuote(annotation.quote, 88)
|
|
1675
|
+
}
|
|
1676
|
+
),
|
|
1677
|
+
onPress: () => setUnavailable(!onReveal(annotation.source, annotationQuoteQuery(annotation))),
|
|
1678
|
+
style: ({ pressed }) => ({ opacity: pressed ? 0.55 : 1, paddingVertical: 2 }),
|
|
1679
|
+
children: text
|
|
1680
|
+
}
|
|
1681
|
+
),
|
|
1682
|
+
unavailable ? /* @__PURE__ */ jsx(
|
|
1683
|
+
Text,
|
|
1684
|
+
{
|
|
1685
|
+
accessibilityLiveRegion: "polite",
|
|
1686
|
+
style: {
|
|
1687
|
+
...fontStyle(theme),
|
|
1688
|
+
fontSize: theme.size.xs,
|
|
1689
|
+
lineHeight: 16,
|
|
1690
|
+
color: theme.colors["status-waiting"]
|
|
1691
|
+
},
|
|
1692
|
+
children: t("timelineAnnotations.sourceIsOutsideTheLoaded")
|
|
1693
|
+
}
|
|
1694
|
+
) : null
|
|
1695
|
+
] });
|
|
1696
|
+
}
|
|
1697
|
+
function NotePreview({ note, ordinal }) {
|
|
1698
|
+
const t = useOpenGeniText();
|
|
1699
|
+
const theme = useNativeTimelineTheme();
|
|
1700
|
+
const [expanded, setExpanded] = useState(false);
|
|
1701
|
+
if (!note) return null;
|
|
1702
|
+
const collapsible = annotationNoteNeedsDisclosure(note);
|
|
1703
|
+
return /* @__PURE__ */ jsxs(View, { style: { marginTop: 2 }, children: [
|
|
1704
|
+
/* @__PURE__ */ jsx(
|
|
1705
|
+
Text,
|
|
1706
|
+
{
|
|
1707
|
+
selectable: true,
|
|
1708
|
+
numberOfLines: expanded ? void 0 : 4,
|
|
1709
|
+
style: {
|
|
1710
|
+
...fontStyle(theme),
|
|
1711
|
+
fontSize: theme.size.sm,
|
|
1712
|
+
lineHeight: 20,
|
|
1713
|
+
color: theme.colors.fg
|
|
1714
|
+
},
|
|
1715
|
+
children: note
|
|
1716
|
+
}
|
|
1717
|
+
),
|
|
1718
|
+
collapsible ? /* @__PURE__ */ jsx(
|
|
1719
|
+
Pressable,
|
|
1720
|
+
{
|
|
1721
|
+
accessibilityRole: "button",
|
|
1722
|
+
accessibilityLabel: expanded ? t("timelineAnnotationChrome.showLessAnnotationOrdinal", { ordinal }) : t("timelineAnnotationChrome.showMoreAnnotationOrdinal", { ordinal }),
|
|
1723
|
+
hitSlop: 8,
|
|
1724
|
+
onPress: () => setExpanded((current) => !current),
|
|
1725
|
+
style: { alignSelf: "flex-start", paddingVertical: 4 },
|
|
1726
|
+
children: /* @__PURE__ */ jsx(
|
|
1727
|
+
Text,
|
|
1728
|
+
{
|
|
1729
|
+
style: {
|
|
1730
|
+
...fontStyle(theme, 500),
|
|
1731
|
+
fontSize: theme.size.xs,
|
|
1732
|
+
color: theme.colors["fg-muted"]
|
|
1733
|
+
},
|
|
1734
|
+
children: expanded ? t("timelineAnnotationChrome.showLess") : t("timelineAnnotationChrome.showMore")
|
|
1735
|
+
}
|
|
1736
|
+
)
|
|
1737
|
+
}
|
|
1738
|
+
) : null
|
|
1739
|
+
] });
|
|
1740
|
+
}
|
|
1741
|
+
function SentAnnotationCards({
|
|
1742
|
+
annotations,
|
|
1743
|
+
onReveal
|
|
1744
|
+
}) {
|
|
1745
|
+
if (annotations.length === 0) return null;
|
|
1746
|
+
return /* @__PURE__ */ jsx(View, { style: { gap: 10 }, children: annotations.map((annotation, index) => {
|
|
1747
|
+
const ordinal = annotationDisplayOrdinal(annotation, index);
|
|
1748
|
+
return /* @__PURE__ */ jsxs(AccentRow, { shrink: true, children: [
|
|
1749
|
+
/* @__PURE__ */ jsx(OrdinalLabel, { ordinal }),
|
|
1750
|
+
/* @__PURE__ */ jsx(QuoteButton, { annotation, onReveal }),
|
|
1751
|
+
/* @__PURE__ */ jsx(NotePreview, { note: annotation.note, ordinal })
|
|
1752
|
+
] }, annotation.id);
|
|
1753
|
+
}) });
|
|
1754
|
+
}
|
|
1755
|
+
function AnnotationsChip({
|
|
1756
|
+
annotations,
|
|
1757
|
+
onPress,
|
|
1758
|
+
onClear,
|
|
1759
|
+
compact = false
|
|
1760
|
+
}) {
|
|
1761
|
+
const t = useOpenGeniText();
|
|
1762
|
+
const theme = useNativeTimelineTheme();
|
|
1763
|
+
const c = theme.colors;
|
|
1764
|
+
if (annotations.length === 0) return null;
|
|
1765
|
+
const countLabel = t("counts.annotations", { count: annotations.length });
|
|
1766
|
+
const incomplete = onClear !== void 0 && annotations.some((item) => !annotationHasNote(item.note));
|
|
1767
|
+
const height = compact ? 26 : 32;
|
|
1768
|
+
return /* @__PURE__ */ jsxs(
|
|
1769
|
+
View,
|
|
1770
|
+
{
|
|
1771
|
+
style: {
|
|
1772
|
+
flexDirection: "row",
|
|
1773
|
+
alignItems: "center",
|
|
1774
|
+
alignSelf: "flex-start",
|
|
1775
|
+
height,
|
|
1776
|
+
borderRadius: height / 2,
|
|
1777
|
+
borderWidth: 1,
|
|
1778
|
+
borderColor: incomplete ? withAlpha(c.accent, 0.45) : c.border,
|
|
1779
|
+
backgroundColor: incomplete ? c["accent-soft"] : c["surface-1"]
|
|
1780
|
+
},
|
|
1781
|
+
children: [
|
|
1782
|
+
/* @__PURE__ */ jsxs(
|
|
1783
|
+
Pressable,
|
|
1784
|
+
{
|
|
1785
|
+
accessibilityRole: "button",
|
|
1786
|
+
accessibilityLabel: t("timelineAnnotations.reviewCountlabel", { countLabel }),
|
|
1787
|
+
hitSlop: { top: (44 - height) / 2, bottom: (44 - height) / 2 },
|
|
1788
|
+
onPress,
|
|
1789
|
+
style: ({ pressed }) => ({
|
|
1790
|
+
flexDirection: "row",
|
|
1791
|
+
alignItems: "center",
|
|
1792
|
+
gap: 6,
|
|
1793
|
+
height,
|
|
1794
|
+
paddingLeft: compact ? 8 : 10,
|
|
1795
|
+
paddingRight: onClear ? 2 : compact ? 8 : 12,
|
|
1796
|
+
opacity: pressed ? 0.6 : 1
|
|
1797
|
+
}),
|
|
1798
|
+
children: [
|
|
1799
|
+
/* @__PURE__ */ jsx(Icon, { name: "quote", size: compact ? 11 : 13, color: c.accent }),
|
|
1800
|
+
/* @__PURE__ */ jsx(
|
|
1801
|
+
Text,
|
|
1802
|
+
{
|
|
1803
|
+
numberOfLines: 1,
|
|
1804
|
+
style: {
|
|
1805
|
+
...fontStyle(theme, 500),
|
|
1806
|
+
fontSize: compact ? theme.size.xs : theme.size.sm,
|
|
1807
|
+
color: c["fg-muted"]
|
|
1808
|
+
},
|
|
1809
|
+
children: countLabel
|
|
1810
|
+
}
|
|
1811
|
+
)
|
|
1812
|
+
]
|
|
1813
|
+
}
|
|
1814
|
+
),
|
|
1815
|
+
onClear ? /* @__PURE__ */ jsx(
|
|
1816
|
+
Pressable,
|
|
1817
|
+
{
|
|
1818
|
+
accessibilityRole: "button",
|
|
1819
|
+
accessibilityLabel: t("timelineAnnotations.removeAllAnnotations"),
|
|
1820
|
+
hitSlop: { top: 6, bottom: 6, right: 6 },
|
|
1821
|
+
onPress: onClear,
|
|
1822
|
+
style: ({ pressed }) => ({
|
|
1823
|
+
width: height,
|
|
1824
|
+
height,
|
|
1825
|
+
alignItems: "center",
|
|
1826
|
+
justifyContent: "center",
|
|
1827
|
+
opacity: pressed ? 0.5 : 1
|
|
1828
|
+
}),
|
|
1829
|
+
children: /* @__PURE__ */ jsx(Icon, { name: "x", size: 13, color: c["fg-subtle"] })
|
|
1830
|
+
}
|
|
1831
|
+
) : null
|
|
1832
|
+
]
|
|
1833
|
+
}
|
|
1834
|
+
);
|
|
1835
|
+
}
|
|
1836
|
+
function AnnotationsSheet({
|
|
1837
|
+
open,
|
|
1838
|
+
onClose,
|
|
1839
|
+
annotations,
|
|
1840
|
+
editable,
|
|
1841
|
+
focusId,
|
|
1842
|
+
onFocusConsumed,
|
|
1843
|
+
onUpdate,
|
|
1844
|
+
onRemove,
|
|
1845
|
+
onReveal,
|
|
1846
|
+
onCommit
|
|
1847
|
+
}) {
|
|
1848
|
+
const t = useOpenGeniText();
|
|
1849
|
+
const theme = useNativeTimelineTheme();
|
|
1850
|
+
const c = theme.colors;
|
|
1851
|
+
const inputs = useRef(/* @__PURE__ */ new Map());
|
|
1852
|
+
const scroll = useRef(null);
|
|
1853
|
+
const rowTops = useRef(/* @__PURE__ */ new Map());
|
|
1854
|
+
const empty = annotations.length === 0;
|
|
1855
|
+
useEffect(() => {
|
|
1856
|
+
if (open && empty) onClose();
|
|
1857
|
+
}, [empty, onClose, open]);
|
|
1858
|
+
const focusNote = (id) => {
|
|
1859
|
+
const top = rowTops.current.get(id);
|
|
1860
|
+
if (top !== void 0) scroll.current?.scrollTo({ y: Math.max(0, top - 8), animated: true });
|
|
1861
|
+
inputs.current.get(id)?.focus();
|
|
1862
|
+
};
|
|
1863
|
+
useEffect(() => {
|
|
1864
|
+
if (!open || !focusId || !editable) return;
|
|
1865
|
+
const timer = setTimeout(() => {
|
|
1866
|
+
focusNote(focusId);
|
|
1867
|
+
onFocusConsumed?.();
|
|
1868
|
+
}, 320);
|
|
1869
|
+
return () => clearTimeout(timer);
|
|
1870
|
+
}, [editable, focusId, open]);
|
|
1871
|
+
const commit = (fromId) => {
|
|
1872
|
+
const incomplete = annotations.filter((item) => !annotationHasNote(item.note));
|
|
1873
|
+
if (incomplete.length === 0) {
|
|
1874
|
+
onCommit?.();
|
|
1875
|
+
return;
|
|
1876
|
+
}
|
|
1877
|
+
const fromIndex = annotations.findIndex((item) => item.id === fromId);
|
|
1878
|
+
const next = incomplete.find((item) => annotations.indexOf(item) > fromIndex) ?? incomplete[0];
|
|
1879
|
+
focusNote(next.id);
|
|
1880
|
+
};
|
|
1881
|
+
const incompleteCount = annotations.filter((item) => !annotationHasNote(item.note)).length;
|
|
1882
|
+
const countLabel = t("counts.annotations", { count: annotations.length });
|
|
1883
|
+
return /* @__PURE__ */ jsxs(
|
|
1884
|
+
BottomSheet,
|
|
1885
|
+
{
|
|
1886
|
+
open: open && !empty,
|
|
1887
|
+
onClose,
|
|
1888
|
+
maxHeightRatio: 0.8,
|
|
1889
|
+
accessibilityLabel: editable ? t("timelineAnnotationsDialog.editQuotedNotes") : t("timelineAnnotationsDialog.quotedNotes"),
|
|
1890
|
+
children: [
|
|
1891
|
+
/* @__PURE__ */ jsxs(
|
|
1892
|
+
View,
|
|
1893
|
+
{
|
|
1894
|
+
style: {
|
|
1895
|
+
flexDirection: "row",
|
|
1896
|
+
alignItems: "center",
|
|
1897
|
+
justifyContent: "space-between",
|
|
1898
|
+
paddingLeft: 20,
|
|
1899
|
+
paddingRight: 8,
|
|
1900
|
+
paddingBottom: 4
|
|
1901
|
+
},
|
|
1902
|
+
children: [
|
|
1903
|
+
/* @__PURE__ */ jsx(
|
|
1904
|
+
Text,
|
|
1905
|
+
{
|
|
1906
|
+
accessibilityRole: "header",
|
|
1907
|
+
style: { ...fontStyle(theme, 600), fontSize: theme.size.md, color: c.fg },
|
|
1908
|
+
children: countLabel
|
|
1909
|
+
}
|
|
1910
|
+
),
|
|
1911
|
+
/* @__PURE__ */ jsx(
|
|
1912
|
+
Pressable,
|
|
1913
|
+
{
|
|
1914
|
+
accessibilityRole: "button",
|
|
1915
|
+
onPress: () => {
|
|
1916
|
+
if (editable && incompleteCount === 0 && onCommit) onCommit();
|
|
1917
|
+
else onClose();
|
|
1918
|
+
},
|
|
1919
|
+
style: ({ pressed }) => ({
|
|
1920
|
+
height: 44,
|
|
1921
|
+
paddingHorizontal: 12,
|
|
1922
|
+
justifyContent: "center",
|
|
1923
|
+
opacity: pressed ? 0.5 : 1
|
|
1924
|
+
}),
|
|
1925
|
+
children: /* @__PURE__ */ jsx(Text, { style: { ...fontStyle(theme, 600), fontSize: theme.size.md, color: c.fg }, children: t("native.timeline.annotations.done") })
|
|
1926
|
+
}
|
|
1927
|
+
)
|
|
1928
|
+
]
|
|
1929
|
+
}
|
|
1930
|
+
),
|
|
1931
|
+
/* @__PURE__ */ jsxs(
|
|
1932
|
+
ScrollView,
|
|
1933
|
+
{
|
|
1934
|
+
ref: scroll,
|
|
1935
|
+
keyboardShouldPersistTaps: "handled",
|
|
1936
|
+
contentContainerStyle: { paddingHorizontal: 20, paddingTop: 8, paddingBottom: 12, gap: 18 },
|
|
1937
|
+
style: { flexGrow: 0 },
|
|
1938
|
+
children: [
|
|
1939
|
+
annotations.map((annotation, index) => {
|
|
1940
|
+
const ordinal = annotationDisplayOrdinal(annotation, index);
|
|
1941
|
+
const last = index === annotations.length - 1;
|
|
1942
|
+
const othersIncomplete = annotations.some(
|
|
1943
|
+
(item) => item.id !== annotation.id && !annotationHasNote(item.note)
|
|
1944
|
+
);
|
|
1945
|
+
return /* @__PURE__ */ jsx(
|
|
1946
|
+
View,
|
|
1947
|
+
{
|
|
1948
|
+
onLayout: (event) => rowTops.current.set(annotation.id, event.nativeEvent.layout.y),
|
|
1949
|
+
children: /* @__PURE__ */ jsxs(AccentRow, { children: [
|
|
1950
|
+
/* @__PURE__ */ jsxs(View, { style: { flexDirection: "row", alignItems: "flex-start", gap: 4 }, children: [
|
|
1951
|
+
/* @__PURE__ */ jsxs(View, { style: { flex: 1, minWidth: 0 }, children: [
|
|
1952
|
+
/* @__PURE__ */ jsx(OrdinalLabel, { ordinal }),
|
|
1953
|
+
/* @__PURE__ */ jsx(
|
|
1954
|
+
QuoteButton,
|
|
1955
|
+
{
|
|
1956
|
+
annotation,
|
|
1957
|
+
onReveal: onReveal ? (source, quote) => {
|
|
1958
|
+
const revealed = onReveal(source, quote);
|
|
1959
|
+
if (revealed) onClose();
|
|
1960
|
+
return revealed;
|
|
1961
|
+
} : void 0
|
|
1962
|
+
}
|
|
1963
|
+
)
|
|
1964
|
+
] }),
|
|
1965
|
+
editable && onRemove ? /* @__PURE__ */ jsx(
|
|
1966
|
+
Pressable,
|
|
1967
|
+
{
|
|
1968
|
+
accessibilityRole: "button",
|
|
1969
|
+
accessibilityLabel: t("timelineAnnotationsDialog.removeAnnotationOrdinal", {
|
|
1970
|
+
ordinal
|
|
1971
|
+
}),
|
|
1972
|
+
onPress: () => onRemove(annotation.id),
|
|
1973
|
+
style: ({ pressed }) => ({
|
|
1974
|
+
width: 36,
|
|
1975
|
+
height: 36,
|
|
1976
|
+
marginTop: -6,
|
|
1977
|
+
marginRight: -10,
|
|
1978
|
+
alignItems: "center",
|
|
1979
|
+
justifyContent: "center",
|
|
1980
|
+
opacity: pressed ? 0.5 : 1
|
|
1981
|
+
}),
|
|
1982
|
+
children: /* @__PURE__ */ jsx(Icon, { name: "x", size: 15, color: c["fg-subtle"] })
|
|
1983
|
+
}
|
|
1984
|
+
) : null
|
|
1985
|
+
] }),
|
|
1986
|
+
editable && onUpdate ? /* @__PURE__ */ jsx(
|
|
1987
|
+
TextInput,
|
|
1988
|
+
{
|
|
1989
|
+
ref: (node) => {
|
|
1990
|
+
if (node) inputs.current.set(annotation.id, node);
|
|
1991
|
+
else inputs.current.delete(annotation.id);
|
|
1992
|
+
},
|
|
1993
|
+
value: annotation.note,
|
|
1994
|
+
onChangeText: (note) => onUpdate(annotation.id, note),
|
|
1995
|
+
placeholder: t("timelineAnnotationChrome.addANote"),
|
|
1996
|
+
placeholderTextColor: c["fg-subtle"],
|
|
1997
|
+
accessibilityLabel: t("timelineAnnotationChrome.note"),
|
|
1998
|
+
maxLength: ANNOTATION_MAX_NOTE_LENGTH,
|
|
1999
|
+
multiline: true,
|
|
2000
|
+
submitBehavior: "submit",
|
|
2001
|
+
returnKeyType: othersIncomplete || last && !onCommit ? "next" : "done",
|
|
2002
|
+
onSubmitEditing: () => commit(annotation.id),
|
|
2003
|
+
style: {
|
|
2004
|
+
...fontStyle(theme),
|
|
2005
|
+
fontSize: theme.size.md,
|
|
2006
|
+
lineHeight: 22,
|
|
2007
|
+
color: c.fg,
|
|
2008
|
+
marginTop: 6,
|
|
2009
|
+
minHeight: 40,
|
|
2010
|
+
maxHeight: 132,
|
|
2011
|
+
paddingHorizontal: 12,
|
|
2012
|
+
paddingTop: 9,
|
|
2013
|
+
paddingBottom: 9,
|
|
2014
|
+
borderRadius: theme.radius.md,
|
|
2015
|
+
backgroundColor: c["surface-2"],
|
|
2016
|
+
borderWidth: 1,
|
|
2017
|
+
borderColor: c.border
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
) : /* @__PURE__ */ jsx(NotePreview, { note: annotation.note, ordinal })
|
|
2021
|
+
] })
|
|
2022
|
+
},
|
|
2023
|
+
annotation.id
|
|
2024
|
+
);
|
|
2025
|
+
}),
|
|
2026
|
+
editable && incompleteCount > 0 ? /* @__PURE__ */ jsx(
|
|
2027
|
+
Text,
|
|
2028
|
+
{
|
|
2029
|
+
style: {
|
|
2030
|
+
...fontStyle(theme),
|
|
2031
|
+
fontSize: theme.size.xs,
|
|
2032
|
+
lineHeight: 16,
|
|
2033
|
+
color: c["fg-subtle"]
|
|
2034
|
+
},
|
|
2035
|
+
children: t("composerMessages.addANoteToEach")
|
|
2036
|
+
}
|
|
2037
|
+
) : null
|
|
2038
|
+
]
|
|
2039
|
+
}
|
|
2040
|
+
)
|
|
2041
|
+
]
|
|
2042
|
+
}
|
|
2043
|
+
);
|
|
2044
|
+
}
|
|
1173
2045
|
var OLDER_HISTORY_PREFETCH_PX = 600;
|
|
1174
2046
|
var USER_MESSAGE_COLLAPSED_PX = 224;
|
|
1175
2047
|
var ROW_GAP_PX = 20;
|
|
2048
|
+
function annotationSources(items) {
|
|
2049
|
+
const sources = /* @__PURE__ */ new Map();
|
|
2050
|
+
for (const item of items) {
|
|
2051
|
+
if (item.kind !== "user-message" && item.kind !== "agent-message") continue;
|
|
2052
|
+
const source = item.annotationSource;
|
|
2053
|
+
if (source) sources.set(source.eventId, source);
|
|
2054
|
+
}
|
|
2055
|
+
return sources;
|
|
2056
|
+
}
|
|
1176
2057
|
function MessageTimeline(props) {
|
|
1177
2058
|
const theme = useNativeTimelineTheme();
|
|
1178
2059
|
const m = useNativeTimelineMessages();
|
|
@@ -1182,6 +2063,8 @@ function MessageTimeline(props) {
|
|
|
1182
2063
|
[t, props.items, props.events]
|
|
1183
2064
|
);
|
|
1184
2065
|
const groups = useMemo(() => groupTimeline(t, items, { readableTurns: true }), [t, items]);
|
|
2066
|
+
const sources = useMemo(() => annotationSources(items), [items]);
|
|
2067
|
+
useNativeTextAnnotation(sources, props.onAnnotate);
|
|
1185
2068
|
const foldMemory = useRef(/* @__PURE__ */ new Map()).current;
|
|
1186
2069
|
const scrollRef = useRef(null);
|
|
1187
2070
|
const following = useRef(!props.focusSequence);
|
|
@@ -1191,6 +2074,72 @@ function MessageTimeline(props) {
|
|
|
1191
2074
|
const [questionNav, setQuestionNav] = useState(null);
|
|
1192
2075
|
const stickyHeaders = useRef(/* @__PURE__ */ new Map()).current;
|
|
1193
2076
|
const scrollY = useRef(0);
|
|
2077
|
+
const sourceNodes = useRef(/* @__PURE__ */ new Map()).current;
|
|
2078
|
+
const [flash, setFlash] = useState(null);
|
|
2079
|
+
const overlayInsetBottom = useRef(0);
|
|
2080
|
+
overlayInsetBottom.current = props.overlayInsetBottom ?? 0;
|
|
2081
|
+
const registerSource = useCallback(
|
|
2082
|
+
(sourceKey, node) => {
|
|
2083
|
+
if (node) sourceNodes.set(sourceKey, node);
|
|
2084
|
+
else sourceNodes.delete(sourceKey);
|
|
2085
|
+
},
|
|
2086
|
+
[sourceNodes]
|
|
2087
|
+
);
|
|
2088
|
+
const revealSource = useCallback(
|
|
2089
|
+
(source, quote) => {
|
|
2090
|
+
const node = sourceNodes.get(source.eventId);
|
|
2091
|
+
const scroller = scrollRef.current?.getNativeScrollRef?.();
|
|
2092
|
+
if (!node || !scroller) return false;
|
|
2093
|
+
following.current = false;
|
|
2094
|
+
const keyboardGone = Keyboard.isVisible() ? new Promise((resolve) => {
|
|
2095
|
+
const done = () => {
|
|
2096
|
+
subscription.remove();
|
|
2097
|
+
clearTimeout(timer);
|
|
2098
|
+
setTimeout(resolve, 60);
|
|
2099
|
+
};
|
|
2100
|
+
const subscription = Keyboard.addListener("keyboardDidHide", done);
|
|
2101
|
+
const timer = setTimeout(done, 600);
|
|
2102
|
+
Keyboard.dismiss();
|
|
2103
|
+
}) : Promise.resolve();
|
|
2104
|
+
const located = quote ? measureQuoteAnchors(source.eventId, [quote]).then(([anchor]) => anchor ?? null) : Promise.resolve(null);
|
|
2105
|
+
void Promise.all([located, keyboardGone]).then(([anchor]) => {
|
|
2106
|
+
scroller.measureInWindow((_scrollX, scrollTop) => {
|
|
2107
|
+
node.measureInWindow((_x, top, _width, height) => {
|
|
2108
|
+
const y = scrollY.current + top - scrollTop;
|
|
2109
|
+
const visible = (viewportHeight.current || 600) - overlayInsetBottom.current;
|
|
2110
|
+
const first = anchor?.boxes[0];
|
|
2111
|
+
const last = anchor?.boxes[anchor.boxes.length - 1];
|
|
2112
|
+
const span = height < visible - 32 || !first || !last ? { top: y, height } : { top: y + first.y, height: last.y + last.height - first.y };
|
|
2113
|
+
const target = span.height < visible - 32 ? span.top - (visible - span.height) / 2 : span.top - 16;
|
|
2114
|
+
const end = Math.max(0, contentHeight.current - (viewportHeight.current || 0));
|
|
2115
|
+
scrollY.current = Math.min(Math.max(0, target), end || Number.POSITIVE_INFINITY);
|
|
2116
|
+
scrollRef.current?.scrollTo({ y: scrollY.current, animated: true });
|
|
2117
|
+
setFlash((current) => ({
|
|
2118
|
+
sourceKey: source.eventId,
|
|
2119
|
+
token: (current?.token ?? 0) + 1,
|
|
2120
|
+
...quote ? { quote } : {}
|
|
2121
|
+
}));
|
|
2122
|
+
});
|
|
2123
|
+
});
|
|
2124
|
+
});
|
|
2125
|
+
return true;
|
|
2126
|
+
},
|
|
2127
|
+
[sourceNodes]
|
|
2128
|
+
);
|
|
2129
|
+
if (props.annotationRevealRef) props.annotationRevealRef.current = revealSource;
|
|
2130
|
+
const draftMarkers = useMemo(
|
|
2131
|
+
() => draftMarkersBySource(props.draftAnnotations),
|
|
2132
|
+
[props.draftAnnotations]
|
|
2133
|
+
);
|
|
2134
|
+
const annotationSourcesValue = useMemo(
|
|
2135
|
+
() => ({
|
|
2136
|
+
register: registerSource,
|
|
2137
|
+
flash,
|
|
2138
|
+
drafts: draftMarkers,
|
|
2139
|
+
onSelectDraft: props.onDraftAnnotationSelect
|
|
2140
|
+
}),
|
|
2141
|
+
[draftMarkers, flash, props.onDraftAnnotationSelect, registerSource]
|
|
2142
|
+
);
|
|
1194
2143
|
const [pinned, setPinned] = useState(
|
|
1195
2144
|
null
|
|
1196
2145
|
);
|
|
@@ -1338,6 +2287,13 @@ function MessageTimeline(props) {
|
|
|
1338
2287
|
},
|
|
1339
2288
|
[requestOlder]
|
|
1340
2289
|
);
|
|
2290
|
+
const followLatestSignal = props.followLatestSignal ?? 0;
|
|
2291
|
+
useEffect(() => {
|
|
2292
|
+
if (!followLatestSignal) return;
|
|
2293
|
+
following.current = true;
|
|
2294
|
+
setShowJump(false);
|
|
2295
|
+
scrollRef.current?.scrollToEnd({ animated: true });
|
|
2296
|
+
}, [followLatestSignal]);
|
|
1341
2297
|
const groupTops = useRef(/* @__PURE__ */ new Map()).current;
|
|
1342
2298
|
const landed = useRef(null);
|
|
1343
2299
|
const [layoutPass, setLayoutPass] = useState(0);
|
|
@@ -1387,9 +2343,10 @@ function MessageTimeline(props) {
|
|
|
1387
2343
|
renderMessageActions: props.renderMessageActions,
|
|
1388
2344
|
renderUserAttachments: props.renderUserAttachments,
|
|
1389
2345
|
onCopy: props.onCopy,
|
|
1390
|
-
reportLiveFold
|
|
2346
|
+
reportLiveFold,
|
|
2347
|
+
onRevealAnnotation: revealSource
|
|
1391
2348
|
};
|
|
1392
|
-
return /* @__PURE__ */ jsx(NativeActivityOptionsProvider, { value: activityOptions, children: /* @__PURE__ */ jsx(FoldMemoryProvider, { value: foldMemory, children: /* @__PURE__ */ jsx(StickyWorkHeaderProvider, { value: registerSticky, children: /* @__PURE__ */ jsx(ReleaseFollowProvider, { value: releaseFollow, children: /* @__PURE__ */ jsxs(View, { style: [{ flex: 1, backgroundColor: theme.colors.bg }, props.style], children: [
|
|
2349
|
+
return /* @__PURE__ */ jsx(AnnotationSourcesContext.Provider, { value: annotationSourcesValue, children: /* @__PURE__ */ jsx(NativeActivityOptionsProvider, { value: activityOptions, children: /* @__PURE__ */ jsx(FoldMemoryProvider, { value: foldMemory, children: /* @__PURE__ */ jsx(StickyWorkHeaderProvider, { value: registerSticky, children: /* @__PURE__ */ jsx(ReleaseFollowProvider, { value: releaseFollow, children: /* @__PURE__ */ jsxs(View, { style: [{ flex: 1, backgroundColor: theme.colors.bg }, props.style], children: [
|
|
1393
2350
|
/* @__PURE__ */ jsxs(
|
|
1394
2351
|
ScrollView,
|
|
1395
2352
|
{
|
|
@@ -1418,7 +2375,13 @@ function MessageTimeline(props) {
|
|
|
1418
2375
|
},
|
|
1419
2376
|
children: [
|
|
1420
2377
|
/* @__PURE__ */ jsxs(View, { children: [
|
|
1421
|
-
props.hasOlder ? /* @__PURE__ */ jsx(
|
|
2378
|
+
props.hasOlder ? /* @__PURE__ */ jsx(
|
|
2379
|
+
OlderHistoryRow,
|
|
2380
|
+
{
|
|
2381
|
+
loading: props.loadingOlder === true,
|
|
2382
|
+
onPress: requestOlder
|
|
2383
|
+
}
|
|
2384
|
+
) : null,
|
|
1422
2385
|
props.header
|
|
1423
2386
|
] }),
|
|
1424
2387
|
groups.length === 0 && props.emptyState ? props.emptyState : null,
|
|
@@ -1522,7 +2485,7 @@ function MessageTimeline(props) {
|
|
|
1522
2485
|
)
|
|
1523
2486
|
}
|
|
1524
2487
|
) : null
|
|
1525
|
-
] }) }) }) }) });
|
|
2488
|
+
] }) }) }) }) }) });
|
|
1526
2489
|
}
|
|
1527
2490
|
function NavButton(props) {
|
|
1528
2491
|
const theme = useNativeTimelineTheme();
|
|
@@ -2013,9 +2976,11 @@ function UserMessageRow({ item, context }) {
|
|
|
2013
2976
|
const theme = useNativeTimelineTheme();
|
|
2014
2977
|
const m = useNativeTimelineMessages();
|
|
2015
2978
|
const failed = item.delivery?.state === "failed";
|
|
2979
|
+
const annotations = item.annotations ?? [];
|
|
2980
|
+
const sourceKey = item.annotationSource?.eventId;
|
|
2016
2981
|
return /* @__PURE__ */ jsx(Animated.View, { entering: FadeIn.duration(180), style: { alignItems: "flex-end" }, children: /* @__PURE__ */ jsxs(View, { style: { maxWidth: "85%", alignItems: "flex-end", gap: 6 }, children: [
|
|
2017
2982
|
item.resources.some((resource) => resource.kind === "file") ? context.renderUserAttachments?.(item) : null,
|
|
2018
|
-
item.text ? /* @__PURE__ */
|
|
2983
|
+
item.text || annotations.length > 0 ? /* @__PURE__ */ jsxs(
|
|
2019
2984
|
View,
|
|
2020
2985
|
{
|
|
2021
2986
|
style: {
|
|
@@ -2029,19 +2994,35 @@ function UserMessageRow({ item, context }) {
|
|
|
2029
2994
|
paddingHorizontal: 16,
|
|
2030
2995
|
paddingVertical: 10
|
|
2031
2996
|
},
|
|
2032
|
-
children:
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2997
|
+
children: [
|
|
2998
|
+
item.text ? /* @__PURE__ */ jsx(CollapsibleUserText, { children: /* @__PURE__ */ jsx(
|
|
2999
|
+
AnnotationSourceView,
|
|
3000
|
+
{
|
|
3001
|
+
sourceKey,
|
|
3002
|
+
style: { marginHorizontal: -6, paddingHorizontal: 6 },
|
|
3003
|
+
children: context.renderMarkdown ? context.renderMarkdown(item.text, { tone: "body" }) : /* @__PURE__ */ jsx(
|
|
3004
|
+
Text,
|
|
3005
|
+
{
|
|
3006
|
+
selectable: true,
|
|
3007
|
+
style: {
|
|
3008
|
+
...fontStyle(theme),
|
|
3009
|
+
fontSize: theme.size.md,
|
|
3010
|
+
lineHeight: 28,
|
|
3011
|
+
color: theme.colors.fg
|
|
3012
|
+
},
|
|
3013
|
+
children: item.text
|
|
3014
|
+
}
|
|
3015
|
+
)
|
|
3016
|
+
}
|
|
3017
|
+
) }) : null,
|
|
3018
|
+
annotations.length > 0 ? /* @__PURE__ */ jsx(View, { style: item.text ? { marginTop: 10, marginBottom: 2 } : { paddingVertical: 2 }, children: /* @__PURE__ */ jsx(
|
|
3019
|
+
SentAnnotationCards,
|
|
3020
|
+
{
|
|
3021
|
+
annotations,
|
|
3022
|
+
onReveal: context.onRevealAnnotation
|
|
3023
|
+
}
|
|
3024
|
+
) }) : null
|
|
3025
|
+
]
|
|
2045
3026
|
}
|
|
2046
3027
|
) : null,
|
|
2047
3028
|
/* @__PURE__ */ jsx(
|
|
@@ -2091,17 +3072,24 @@ function UserMessageRow({ item, context }) {
|
|
|
2091
3072
|
function AgentMessageRow({ item, context }) {
|
|
2092
3073
|
const theme = useNativeTimelineTheme();
|
|
2093
3074
|
return /* @__PURE__ */ jsxs(Animated.View, { entering: FadeIn.duration(180), style: { minWidth: 0 }, children: [
|
|
2094
|
-
|
|
2095
|
-
|
|
3075
|
+
/* @__PURE__ */ jsx(
|
|
3076
|
+
AnnotationSourceView,
|
|
2096
3077
|
{
|
|
2097
|
-
|
|
2098
|
-
style: {
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
3078
|
+
sourceKey: item.annotationSource?.eventId,
|
|
3079
|
+
style: { marginHorizontal: -8, paddingHorizontal: 8 },
|
|
3080
|
+
children: context.renderMarkdown ? context.renderMarkdown(item.text, { tone: "body", streaming: item.streaming }) : /* @__PURE__ */ jsx(
|
|
3081
|
+
Text,
|
|
3082
|
+
{
|
|
3083
|
+
selectable: true,
|
|
3084
|
+
style: {
|
|
3085
|
+
...fontStyle(theme),
|
|
3086
|
+
fontSize: theme.size.md,
|
|
3087
|
+
lineHeight: 28,
|
|
3088
|
+
color: theme.colors.fg
|
|
3089
|
+
},
|
|
3090
|
+
children: item.text
|
|
3091
|
+
}
|
|
3092
|
+
)
|
|
2105
3093
|
}
|
|
2106
3094
|
),
|
|
2107
3095
|
item.streaming ? null : /* @__PURE__ */ jsx(
|
|
@@ -4333,7 +5321,7 @@ function StatusDot({
|
|
|
4333
5321
|
return;
|
|
4334
5322
|
}
|
|
4335
5323
|
opacity.value = withRepeat(
|
|
4336
|
-
withTiming(0.5, { duration: 1e3, easing: Easing.bezier(0.4, 0, 0.6, 1) }),
|
|
5324
|
+
withTiming(0.5, { duration: 1e3, easing: Easing$1.bezier(0.4, 0, 0.6, 1) }),
|
|
4337
5325
|
-1,
|
|
4338
5326
|
true
|
|
4339
5327
|
);
|
|
@@ -4603,145 +5591,6 @@ function SessionHeaderTitle({
|
|
|
4603
5591
|
}
|
|
4604
5592
|
);
|
|
4605
5593
|
}
|
|
4606
|
-
function BottomSheet(props) {
|
|
4607
|
-
const t = useOpenGeniText();
|
|
4608
|
-
const theme = useNativeTimelineTheme();
|
|
4609
|
-
const c = theme.colors;
|
|
4610
|
-
const insets = useSafeAreaInsets();
|
|
4611
|
-
const { height } = useWindowDimensions();
|
|
4612
|
-
const [mounted, setMounted] = useState(props.open);
|
|
4613
|
-
const progress = useRef(new Animated$1.Value(0)).current;
|
|
4614
|
-
const drag = useRef(new Animated$1.Value(0)).current;
|
|
4615
|
-
const onClose = useRef(props.onClose);
|
|
4616
|
-
onClose.current = props.onClose;
|
|
4617
|
-
useEffect(() => {
|
|
4618
|
-
let cancelled = false;
|
|
4619
|
-
if (props.open) {
|
|
4620
|
-
setMounted(true);
|
|
4621
|
-
drag.setValue(0);
|
|
4622
|
-
void AccessibilityInfo.isReduceMotionEnabled().then((reduce) => {
|
|
4623
|
-
if (cancelled) return;
|
|
4624
|
-
Animated$1.timing(progress, {
|
|
4625
|
-
toValue: 1,
|
|
4626
|
-
duration: reduce ? 0 : 260,
|
|
4627
|
-
easing: Easing$1.bezier(0.22, 1, 0.36, 1),
|
|
4628
|
-
useNativeDriver: true
|
|
4629
|
-
}).start();
|
|
4630
|
-
});
|
|
4631
|
-
} else if (mounted) {
|
|
4632
|
-
Animated$1.timing(progress, {
|
|
4633
|
-
toValue: 0,
|
|
4634
|
-
duration: 200,
|
|
4635
|
-
easing: Easing$1.in(Easing$1.quad),
|
|
4636
|
-
useNativeDriver: true
|
|
4637
|
-
}).start(({ finished }) => {
|
|
4638
|
-
if (finished && !cancelled) setMounted(false);
|
|
4639
|
-
});
|
|
4640
|
-
}
|
|
4641
|
-
return () => {
|
|
4642
|
-
cancelled = true;
|
|
4643
|
-
};
|
|
4644
|
-
}, [drag, mounted, progress, props.open]);
|
|
4645
|
-
const pan = useRef(
|
|
4646
|
-
PanResponder.create({
|
|
4647
|
-
onMoveShouldSetPanResponder: (_event, gesture) => gesture.dy > 6 && Math.abs(gesture.dy) > Math.abs(gesture.dx),
|
|
4648
|
-
onPanResponderMove: (_event, gesture) => drag.setValue(Math.max(0, gesture.dy)),
|
|
4649
|
-
onPanResponderRelease: (_event, gesture) => {
|
|
4650
|
-
if (gesture.dy > 90 || gesture.vy > 0.9) onClose.current();
|
|
4651
|
-
else Animated$1.spring(drag, { toValue: 0, useNativeDriver: true, bounciness: 0 }).start();
|
|
4652
|
-
},
|
|
4653
|
-
onPanResponderTerminate: () => Animated$1.spring(drag, { toValue: 0, useNativeDriver: true, bounciness: 0 }).start()
|
|
4654
|
-
})
|
|
4655
|
-
).current;
|
|
4656
|
-
if (!mounted) return null;
|
|
4657
|
-
const translateY = Animated$1.add(
|
|
4658
|
-
progress.interpolate({ inputRange: [0, 1], outputRange: [height, 0] }),
|
|
4659
|
-
drag
|
|
4660
|
-
);
|
|
4661
|
-
return /* @__PURE__ */ jsx(
|
|
4662
|
-
Modal,
|
|
4663
|
-
{
|
|
4664
|
-
visible: true,
|
|
4665
|
-
transparent: true,
|
|
4666
|
-
animationType: "none",
|
|
4667
|
-
statusBarTranslucent: true,
|
|
4668
|
-
onRequestClose: props.onClose,
|
|
4669
|
-
children: /* @__PURE__ */ jsxs(
|
|
4670
|
-
KeyboardAvoidingView,
|
|
4671
|
-
{
|
|
4672
|
-
behavior: Platform.OS === "ios" ? "padding" : void 0,
|
|
4673
|
-
style: { flex: 1, justifyContent: "flex-end" },
|
|
4674
|
-
children: [
|
|
4675
|
-
/* @__PURE__ */ jsx(
|
|
4676
|
-
Animated$1.View,
|
|
4677
|
-
{
|
|
4678
|
-
style: {
|
|
4679
|
-
position: "absolute",
|
|
4680
|
-
top: 0,
|
|
4681
|
-
right: 0,
|
|
4682
|
-
bottom: 0,
|
|
4683
|
-
left: 0,
|
|
4684
|
-
backgroundColor: "rgba(0, 0, 0, 0.4)",
|
|
4685
|
-
opacity: progress
|
|
4686
|
-
},
|
|
4687
|
-
children: /* @__PURE__ */ jsx(
|
|
4688
|
-
Pressable,
|
|
4689
|
-
{
|
|
4690
|
-
style: { flex: 1 },
|
|
4691
|
-
onPress: props.onClose,
|
|
4692
|
-
accessibilityRole: "button",
|
|
4693
|
-
accessibilityLabel: t("native.timeline.sheet.close")
|
|
4694
|
-
}
|
|
4695
|
-
)
|
|
4696
|
-
}
|
|
4697
|
-
),
|
|
4698
|
-
/* @__PURE__ */ jsxs(
|
|
4699
|
-
Animated$1.View,
|
|
4700
|
-
{
|
|
4701
|
-
accessibilityViewIsModal: true,
|
|
4702
|
-
accessibilityLabel: props.accessibilityLabel,
|
|
4703
|
-
style: {
|
|
4704
|
-
maxHeight: height * (props.maxHeightRatio ?? 0.85),
|
|
4705
|
-
backgroundColor: c.bg,
|
|
4706
|
-
borderTopLeftRadius: 16,
|
|
4707
|
-
borderTopRightRadius: 16,
|
|
4708
|
-
paddingBottom: Math.max(insets.bottom, 12),
|
|
4709
|
-
transform: [{ translateY }],
|
|
4710
|
-
shadowColor: "#000",
|
|
4711
|
-
shadowOpacity: 0.12,
|
|
4712
|
-
shadowRadius: 16,
|
|
4713
|
-
shadowOffset: { width: 0, height: -2 },
|
|
4714
|
-
elevation: 16
|
|
4715
|
-
},
|
|
4716
|
-
children: [
|
|
4717
|
-
/* @__PURE__ */ jsx(
|
|
4718
|
-
View,
|
|
4719
|
-
{
|
|
4720
|
-
...pan.panHandlers,
|
|
4721
|
-
style: { alignItems: "center", paddingTop: 8, paddingBottom: 4 },
|
|
4722
|
-
children: /* @__PURE__ */ jsx(
|
|
4723
|
-
View,
|
|
4724
|
-
{
|
|
4725
|
-
style: {
|
|
4726
|
-
width: 36,
|
|
4727
|
-
height: 5,
|
|
4728
|
-
borderRadius: 3,
|
|
4729
|
-
backgroundColor: c["border-strong"] ?? c.border
|
|
4730
|
-
}
|
|
4731
|
-
}
|
|
4732
|
-
)
|
|
4733
|
-
}
|
|
4734
|
-
),
|
|
4735
|
-
props.children
|
|
4736
|
-
]
|
|
4737
|
-
}
|
|
4738
|
-
)
|
|
4739
|
-
]
|
|
4740
|
-
}
|
|
4741
|
-
)
|
|
4742
|
-
}
|
|
4743
|
-
);
|
|
4744
|
-
}
|
|
4745
5594
|
var CompactSignalsContext = createContext(false);
|
|
4746
5595
|
function SessionSignals(props) {
|
|
4747
5596
|
const m = useNativeTimelineMessages();
|
|
@@ -5004,6 +5853,7 @@ function QueueDock({
|
|
|
5004
5853
|
queue,
|
|
5005
5854
|
composer,
|
|
5006
5855
|
onComposerFocus,
|
|
5856
|
+
onReviewAnnotations,
|
|
5007
5857
|
leading,
|
|
5008
5858
|
singleSend = false
|
|
5009
5859
|
}) {
|
|
@@ -5163,6 +6013,42 @@ function QueueDock({
|
|
|
5163
6013
|
children: label
|
|
5164
6014
|
}
|
|
5165
6015
|
),
|
|
6016
|
+
annotationCount > 0 && onReviewAnnotations ? /* @__PURE__ */ jsxs(
|
|
6017
|
+
Pressable,
|
|
6018
|
+
{
|
|
6019
|
+
accessibilityRole: "button",
|
|
6020
|
+
accessibilityLabel: t("timelineAnnotations.reviewCountlabel", {
|
|
6021
|
+
countLabel: t("counts.annotations", { count: annotationCount })
|
|
6022
|
+
}),
|
|
6023
|
+
hitSlop: 8,
|
|
6024
|
+
onPress: () => onReviewAnnotations(turn.annotations ?? []),
|
|
6025
|
+
style: ({ pressed }) => ({
|
|
6026
|
+
flexDirection: "row",
|
|
6027
|
+
alignItems: "center",
|
|
6028
|
+
gap: 3,
|
|
6029
|
+
height: 22,
|
|
6030
|
+
paddingHorizontal: 7,
|
|
6031
|
+
borderRadius: 11,
|
|
6032
|
+
backgroundColor: c["accent-soft"],
|
|
6033
|
+
opacity: pressed ? 0.6 : 1
|
|
6034
|
+
}),
|
|
6035
|
+
children: [
|
|
6036
|
+
/* @__PURE__ */ jsx(Icon, { name: "quote", size: 10, color: c["fg-muted"] }),
|
|
6037
|
+
/* @__PURE__ */ jsx(
|
|
6038
|
+
Text,
|
|
6039
|
+
{
|
|
6040
|
+
style: {
|
|
6041
|
+
...fontStyle(theme, 500),
|
|
6042
|
+
fontSize: 11,
|
|
6043
|
+
color: c["fg-muted"],
|
|
6044
|
+
fontVariant: ["tabular-nums"]
|
|
6045
|
+
},
|
|
6046
|
+
children: annotationCount
|
|
6047
|
+
}
|
|
6048
|
+
)
|
|
6049
|
+
]
|
|
6050
|
+
}
|
|
6051
|
+
) : null,
|
|
5166
6052
|
turns.length > 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5167
6053
|
/* @__PURE__ */ jsx(
|
|
5168
6054
|
RowAction,
|
|
@@ -5364,9 +6250,27 @@ function SessionScreenBody({
|
|
|
5364
6250
|
...timelineProps
|
|
5365
6251
|
}) {
|
|
5366
6252
|
const theme = useNativeTimelineTheme();
|
|
6253
|
+
const t = useOpenGeniText();
|
|
5367
6254
|
const m = useNativeTimelineMessages();
|
|
5368
6255
|
const { composer, queue, humanInput, approvals, control, attachments } = controller;
|
|
5369
6256
|
const composerInput = useRef(null);
|
|
6257
|
+
const annotationReveal = useRef(null);
|
|
6258
|
+
const draftAnnotations = composer.annotations ?? [];
|
|
6259
|
+
const annotationsIncomplete = draftAnnotations.some(
|
|
6260
|
+
(annotation) => annotation.note.trim().length === 0
|
|
6261
|
+
);
|
|
6262
|
+
const reviewTargetId = composer.annotationReviewTargetId ?? null;
|
|
6263
|
+
const [reviewOpen, setReviewOpen] = useState(false);
|
|
6264
|
+
useEffect(() => {
|
|
6265
|
+
if (reviewTargetId) setReviewOpen(true);
|
|
6266
|
+
}, [reviewTargetId]);
|
|
6267
|
+
const closeReview = useCallback(() => {
|
|
6268
|
+
setReviewOpen(false);
|
|
6269
|
+
composer.clearAnnotationReviewTarget?.();
|
|
6270
|
+
}, [composer]);
|
|
6271
|
+
const [queuedReview, setQueuedReview] = useState(null);
|
|
6272
|
+
const [followLatestSignal, setFollowLatestSignal] = useState(0);
|
|
6273
|
+
const followLatest = useCallback(() => setFollowLatestSignal((value) => value + 1), []);
|
|
5370
6274
|
const [composerHeight, setComposerHeight] = useState(120);
|
|
5371
6275
|
const items = useMemo(
|
|
5372
6276
|
() => conversationTimeline(controller.timeline, queue, composer),
|
|
@@ -5409,6 +6313,11 @@ function SessionScreenBody({
|
|
|
5409
6313
|
/* @__PURE__ */ jsx(
|
|
5410
6314
|
MessageTimeline,
|
|
5411
6315
|
{
|
|
6316
|
+
onAnnotate: composer.addAnnotation,
|
|
6317
|
+
draftAnnotations: composer.annotations,
|
|
6318
|
+
onDraftAnnotationSelect: composer.requestAnnotationReview,
|
|
6319
|
+
annotationRevealRef: annotationReveal,
|
|
6320
|
+
followLatestSignal,
|
|
5412
6321
|
...timelineProps,
|
|
5413
6322
|
hasOlder: controller.hasOlder,
|
|
5414
6323
|
loadingOlder: controller.loadingOlder,
|
|
@@ -5467,12 +6376,29 @@ function SessionScreenBody({
|
|
|
5467
6376
|
onActionFeedback: composerSlots?.onActionFeedback,
|
|
5468
6377
|
value: composer.value,
|
|
5469
6378
|
onChangeText: composer.setValue,
|
|
5470
|
-
|
|
6379
|
+
// A quote without its note cannot be sent: Send opens that note instead
|
|
6380
|
+
// of staying disabled with no reason given.
|
|
6381
|
+
onSend: () => {
|
|
6382
|
+
if (annotationsIncomplete) composer.requestAnnotationReview?.();
|
|
6383
|
+
else {
|
|
6384
|
+
followLatest();
|
|
6385
|
+
void composer.send();
|
|
6386
|
+
}
|
|
6387
|
+
},
|
|
5471
6388
|
// The other choice beside Send while the agent works: Queue when
|
|
5472
6389
|
// Send steers, Steer when Send queues.
|
|
5473
6390
|
alternateSend: composer.alternateSend ?? null,
|
|
5474
|
-
...composer.sendAlternate ? {
|
|
5475
|
-
|
|
6391
|
+
...composer.sendAlternate ? {
|
|
6392
|
+
onAlternateSend: () => {
|
|
6393
|
+
if (annotationsIncomplete) {
|
|
6394
|
+
composer.requestAnnotationReview?.();
|
|
6395
|
+
return;
|
|
6396
|
+
}
|
|
6397
|
+
followLatest();
|
|
6398
|
+
void composer.sendAlternate?.();
|
|
6399
|
+
}
|
|
6400
|
+
} : {},
|
|
6401
|
+
canSend: (composer.canSend || annotationsIncomplete && !composer.sending) && !busy,
|
|
5476
6402
|
sending: composer.sending,
|
|
5477
6403
|
running: controller.runActive,
|
|
5478
6404
|
paused,
|
|
@@ -5499,7 +6425,41 @@ function SessionScreenBody({
|
|
|
5499
6425
|
) : null,
|
|
5500
6426
|
header: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5501
6427
|
composerSlots?.header,
|
|
5502
|
-
/* @__PURE__ */ jsx(AttachmentChips, { attachments })
|
|
6428
|
+
/* @__PURE__ */ jsx(AttachmentChips, { attachments }),
|
|
6429
|
+
draftAnnotations.length > 0 && composer.removeAnnotation ? /* @__PURE__ */ jsx(View, { style: { paddingHorizontal: 12, paddingTop: 10 }, children: /* @__PURE__ */ jsx(
|
|
6430
|
+
AnnotationsChip,
|
|
6431
|
+
{
|
|
6432
|
+
annotations: draftAnnotations,
|
|
6433
|
+
onPress: () => composer.requestAnnotationReview?.(),
|
|
6434
|
+
onClear: () => {
|
|
6435
|
+
const removeAll = () => {
|
|
6436
|
+
for (const annotation of draftAnnotations) {
|
|
6437
|
+
composer.removeAnnotation?.(annotation.id);
|
|
6438
|
+
}
|
|
6439
|
+
};
|
|
6440
|
+
if (!draftAnnotations.some((item) => annotationHasNote(item.note))) {
|
|
6441
|
+
removeAll();
|
|
6442
|
+
return;
|
|
6443
|
+
}
|
|
6444
|
+
Alert.alert(
|
|
6445
|
+
t("native.timeline.annotations.removeAllTitle", {
|
|
6446
|
+
count: draftAnnotations.length
|
|
6447
|
+
}),
|
|
6448
|
+
t("native.timeline.annotations.removeAllMessage", {
|
|
6449
|
+
count: draftAnnotations.filter((item) => annotationHasNote(item.note)).length
|
|
6450
|
+
}),
|
|
6451
|
+
[
|
|
6452
|
+
{ text: t("native.timeline.annotations.cancel"), style: "cancel" },
|
|
6453
|
+
{
|
|
6454
|
+
text: t("native.timeline.annotations.removeAllConfirm"),
|
|
6455
|
+
style: "destructive",
|
|
6456
|
+
onPress: removeAll
|
|
6457
|
+
}
|
|
6458
|
+
]
|
|
6459
|
+
);
|
|
6460
|
+
}
|
|
6461
|
+
}
|
|
6462
|
+
) }) : null
|
|
5503
6463
|
] }),
|
|
5504
6464
|
above: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5505
6465
|
/* @__PURE__ */ jsx(
|
|
@@ -5509,6 +6469,7 @@ function SessionScreenBody({
|
|
|
5509
6469
|
composer,
|
|
5510
6470
|
singleSend: composer.singleSend === true,
|
|
5511
6471
|
onComposerFocus: () => composerInput.current?.focus(),
|
|
6472
|
+
onReviewAnnotations: setQueuedReview,
|
|
5512
6473
|
leading: /* @__PURE__ */ jsx(
|
|
5513
6474
|
SessionSignals,
|
|
5514
6475
|
{
|
|
@@ -5541,7 +6502,35 @@ function SessionScreenBody({
|
|
|
5541
6502
|
}
|
|
5542
6503
|
) : null
|
|
5543
6504
|
] })
|
|
5544
|
-
})
|
|
6505
|
+
}),
|
|
6506
|
+
/* @__PURE__ */ jsx(
|
|
6507
|
+
AnnotationsSheet,
|
|
6508
|
+
{
|
|
6509
|
+
open: reviewOpen,
|
|
6510
|
+
onClose: closeReview,
|
|
6511
|
+
annotations: draftAnnotations,
|
|
6512
|
+
editable: Boolean(composer.updateAnnotation),
|
|
6513
|
+
focusId: reviewTargetId,
|
|
6514
|
+
onFocusConsumed: composer.clearAnnotationReviewTarget,
|
|
6515
|
+
onUpdate: composer.updateAnnotation,
|
|
6516
|
+
onRemove: composer.removeAnnotation,
|
|
6517
|
+
onReveal: (source, quote) => annotationReveal.current?.(source, quote) ?? false,
|
|
6518
|
+
onCommit: () => {
|
|
6519
|
+
closeReview();
|
|
6520
|
+
setTimeout(() => composerInput.current?.focus(), 250);
|
|
6521
|
+
}
|
|
6522
|
+
}
|
|
6523
|
+
),
|
|
6524
|
+
/* @__PURE__ */ jsx(
|
|
6525
|
+
AnnotationsSheet,
|
|
6526
|
+
{
|
|
6527
|
+
open: queuedReview !== null,
|
|
6528
|
+
onClose: () => setQueuedReview(null),
|
|
6529
|
+
annotations: queuedReview ?? [],
|
|
6530
|
+
editable: false,
|
|
6531
|
+
onReveal: (source, quote) => annotationReveal.current?.(source, quote) ?? false
|
|
6532
|
+
}
|
|
6533
|
+
)
|
|
5545
6534
|
] });
|
|
5546
6535
|
}
|
|
5547
6536
|
function useAutoRecover(failed, live, refresh) {
|
|
@@ -7527,6 +8516,6 @@ function NativeInboxList({
|
|
|
7527
8516
|
] });
|
|
7528
8517
|
}
|
|
7529
8518
|
|
|
7530
|
-
export { ActivityRail, ActivityRow, ApprovalStrip, AttachmentChips, BottomSheet, Button, ComposerPill, FeedbackSheet, HumanInputCard, IconButton, MessageTimeline, ModelMark, ModelPickerSheet, NativeInboxList, NativeMessageAttachments, NativeSessionScreen, PreparingState, PresentedToolRow, QueueDock, RollingActivity, SectionLabel, SessionActionsButton, SessionCommandsList, SessionComposer, SessionHeaderTitle, SessionRow, SessionRowList, SessionSignals, SessionStatusBadge, StatusDot, TurnFeedbackButtons, TurnRailFrame, TurnSummary, defaultApprovalStripMessages, isNeedsYouKind, nativeInboxAttentionCount, useNativeInbox, useTurnRatings };
|
|
8519
|
+
export { ActivityRail, ActivityRow, AnnotationsChip, AnnotationsSheet, ApprovalStrip, AttachmentChips, BottomSheet, Button, ComposerPill, FeedbackSheet, HumanInputCard, IconButton, MessageTimeline, ModelMark, ModelPickerSheet, NativeInboxList, NativeMessageAttachments, NativeSessionScreen, PreparingState, PresentedToolRow, QueueDock, RollingActivity, SectionLabel, SessionActionsButton, SessionCommandsList, SessionComposer, SessionHeaderTitle, SessionRow, SessionRowList, SessionSignals, SessionStatusBadge, StatusDot, TurnFeedbackButtons, TurnRailFrame, TurnSummary, defaultApprovalStripMessages, isNeedsYouKind, nativeInboxAttentionCount, useNativeInbox, useTurnRatings };
|
|
7531
8520
|
//# sourceMappingURL=index.js.map
|
|
7532
8521
|
//# sourceMappingURL=index.js.map
|