@opengeni/react-native 1.4.5-canary.37615713321001
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/LICENSE +190 -0
- package/README.md +74 -0
- package/dist/adapters.d.ts +53 -0
- package/dist/adapters.js +3 -0
- package/dist/adapters.js.map +1 -0
- package/dist/attachments.d.ts +75 -0
- package/dist/chunk-3VSZAQ7G.js +391 -0
- package/dist/chunk-3VSZAQ7G.js.map +1 -0
- package/dist/chunk-5ZVK7WKA.js +88 -0
- package/dist/chunk-5ZVK7WKA.js.map +1 -0
- package/dist/chunk-EEDIMY3L.js +240 -0
- package/dist/chunk-EEDIMY3L.js.map +1 -0
- package/dist/chunk-M23SDI4R.js +83 -0
- package/dist/chunk-M23SDI4R.js.map +1 -0
- package/dist/chunk-PHJBSAR3.js +2006 -0
- package/dist/chunk-PHJBSAR3.js.map +1 -0
- package/dist/environment.d.ts +19 -0
- package/dist/expo.d.ts +25 -0
- package/dist/expo.js +267 -0
- package/dist/expo.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +3345 -0
- package/dist/index.js.map +1 -0
- package/dist/presentation.d.ts +262 -0
- package/dist/read-acknowledgement.d.ts +39 -0
- package/dist/realtime/call-events.d.ts +11 -0
- package/dist/realtime/call-view.d.ts +26 -0
- package/dist/realtime/expo-call.d.ts +11 -0
- package/dist/realtime/native-call.d.ts +104 -0
- package/dist/realtime/native-realtime.d.ts +35 -0
- package/dist/realtime/use-native-session-realtime.d.ts +25 -0
- package/dist/session-view.d.ts +87 -0
- package/dist/timeline/activity.d.ts +34 -0
- package/dist/timeline/composer.d.ts +86 -0
- package/dist/timeline/controls.d.ts +27 -0
- package/dist/timeline/decisions.d.ts +29 -0
- package/dist/timeline/feedback.d.ts +26 -0
- package/dist/timeline/icon-nodes.generated.d.ts +738 -0
- package/dist/timeline/icon.d.ts +11 -0
- package/dist/timeline/index.d.ts +32 -0
- package/dist/timeline/index.js +5419 -0
- package/dist/timeline/index.js.map +1 -0
- package/dist/timeline/markdown.d.ts +11 -0
- package/dist/timeline/markdown.js +415 -0
- package/dist/timeline/markdown.js.map +1 -0
- package/dist/timeline/message-attachments.d.ts +13 -0
- package/dist/timeline/message-timeline.d.ts +36 -0
- package/dist/timeline/model-picker.d.ts +17 -0
- package/dist/timeline/primitives.d.ts +85 -0
- package/dist/timeline/queue-dock.d.ts +19 -0
- package/dist/timeline/session-actions.d.ts +34 -0
- package/dist/timeline/session-list.d.ts +50 -0
- package/dist/timeline/session-screen.d.ts +35 -0
- package/dist/timeline/session-signals.d.ts +37 -0
- package/dist/timeline/sheet.d.ts +14 -0
- package/dist/timeline/theme.d.ts +58 -0
- package/dist/timeline/thinking-orb.d.ts +13 -0
- package/dist/timeline/turn.d.ts +80 -0
- package/dist/ui/attention.d.ts +14 -0
- package/dist/ui/cards.d.ts +21 -0
- package/dist/ui/composer.d.ts +21 -0
- package/dist/ui/format.d.ts +13 -0
- package/dist/ui/icons.d.ts +9 -0
- package/dist/ui/index.d.ts +12 -0
- package/dist/ui/index.js +1757 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/steps-sheet.d.ts +10 -0
- package/dist/ui/theme.d.ts +63 -0
- package/dist/ui/timeline.d.ts +48 -0
- package/dist/ui/web-tokens.gen.d.ts +90 -0
- package/dist/use-native-session.d.ts +40 -0
- package/dist/view-model.d.ts +52 -0
- package/dist/voice-input.d.ts +102 -0
- package/dist/webrtc.d.ts +9 -0
- package/dist/webrtc.js +19 -0
- package/dist/webrtc.js.map +1 -0
- package/expo-module.config.json +7 -0
- package/ios/OpenGeniCall.podspec +22 -0
- package/ios/OpenGeniCallAppDelegateSubscriber.swift +29 -0
- package/ios/OpenGeniCallCenter.swift +189 -0
- package/ios/OpenGeniCallModule.swift +64 -0
- package/package.json +93 -0
- package/src/adapters.ts +150 -0
- package/src/attachments.ts +396 -0
- package/src/environment.tsx +214 -0
- package/src/expo.ts +295 -0
- package/src/index.ts +98 -0
- package/src/presentation.ts +285 -0
- package/src/read-acknowledgement.ts +72 -0
- package/src/realtime/call-events.ts +41 -0
- package/src/realtime/call-view.tsx +220 -0
- package/src/realtime/expo-call.ts +49 -0
- package/src/realtime/native-call.ts +266 -0
- package/src/realtime/native-realtime.ts +115 -0
- package/src/realtime/use-native-session-realtime.ts +29 -0
- package/src/session-view.tsx +2251 -0
- package/src/timeline/activity.tsx +736 -0
- package/src/timeline/composer.tsx +686 -0
- package/src/timeline/controls.tsx +151 -0
- package/src/timeline/decisions.tsx +651 -0
- package/src/timeline/feedback.tsx +251 -0
- package/src/timeline/icon-nodes.generated.ts +1830 -0
- package/src/timeline/icon.tsx +44 -0
- package/src/timeline/index.ts +67 -0
- package/src/timeline/markdown.tsx +510 -0
- package/src/timeline/message-attachments.tsx +155 -0
- package/src/timeline/message-timeline.tsx +1042 -0
- package/src/timeline/model-picker.tsx +450 -0
- package/src/timeline/primitives.tsx +561 -0
- package/src/timeline/queue-dock.tsx +331 -0
- package/src/timeline/session-actions.tsx +379 -0
- package/src/timeline/session-list.tsx +338 -0
- package/src/timeline/session-screen.tsx +488 -0
- package/src/timeline/session-signals.tsx +312 -0
- package/src/timeline/sheet.tsx +153 -0
- package/src/timeline/theme.tsx +128 -0
- package/src/timeline/thinking-orb.tsx +93 -0
- package/src/timeline/turn.tsx +569 -0
- package/src/ui/attention.tsx +220 -0
- package/src/ui/cards.tsx +267 -0
- package/src/ui/composer.tsx +296 -0
- package/src/ui/format.ts +86 -0
- package/src/ui/icons.tsx +131 -0
- package/src/ui/index.ts +18 -0
- package/src/ui/steps-sheet.tsx +71 -0
- package/src/ui/theme.ts +261 -0
- package/src/ui/timeline.tsx +837 -0
- package/src/ui/web-tokens.gen.ts +94 -0
- package/src/use-native-session.ts +219 -0
- package/src/view-model.ts +485 -0
- package/src/voice-input.ts +382 -0
- package/src/webrtc.ts +30 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type TextStyle } from "react-native";
|
|
2
|
+
import { type OpenGeniLinkTarget } from "@opengeni/sdk";
|
|
3
|
+
import type { NativeMarkdownRenderer } from "./message-timeline.js";
|
|
4
|
+
import { type NativeTimelineTheme } from "./theme.js";
|
|
5
|
+
export declare function webMarkdownStyles(theme: NativeTimelineTheme, tone: "body" | "muted"): Record<string, TextStyle>;
|
|
6
|
+
export declare function createWebMarkdownRenderer(options?: {
|
|
7
|
+
onLinkPress?: (url: string) => boolean;
|
|
8
|
+
onCopy?: (text: string) => void;
|
|
9
|
+
/** OpenGeni links (sandbox files, artifacts, Sites); never handed to the OS. */
|
|
10
|
+
onOpenGeniLink?: (target: OpenGeniLinkTarget) => void;
|
|
11
|
+
}): NativeMarkdownRenderer;
|
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import { withAlpha } from '../chunk-3VSZAQ7G.js';
|
|
2
|
+
import { fontStyle, MONO_FALLBACK, insetSurface, useNativeTimelineTheme, Icon } from '../chunk-PHJBSAR3.js';
|
|
3
|
+
import { createContext, useMemo, useState, useContext } from 'react';
|
|
4
|
+
import { Text, View, ScrollView, Pressable } from 'react-native';
|
|
5
|
+
import Markdown, { MarkdownIt, renderRules } from 'react-native-markdown-display';
|
|
6
|
+
import { parseOpenGeniLink, isReservedOpenGeniLink } from '@opengeni/sdk';
|
|
7
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
var PARSER = (() => {
|
|
10
|
+
const parser = MarkdownIt({ typographer: false, linkify: true });
|
|
11
|
+
parser.linkify.set({ fuzzyLink: false, fuzzyEmail: false });
|
|
12
|
+
return parser;
|
|
13
|
+
})();
|
|
14
|
+
function webMarkdownStyles(theme, tone) {
|
|
15
|
+
const c = theme.colors;
|
|
16
|
+
const muted = tone === "muted";
|
|
17
|
+
const size = muted ? theme.size.base : theme.size.md;
|
|
18
|
+
const line = muted ? 24 : 28;
|
|
19
|
+
const body = {
|
|
20
|
+
...fontStyle(theme),
|
|
21
|
+
color: muted ? c["fg-muted"] : c.fg,
|
|
22
|
+
fontSize: size,
|
|
23
|
+
lineHeight: line
|
|
24
|
+
};
|
|
25
|
+
const mono = fontStyle(theme, 400, "mono");
|
|
26
|
+
const heading = { ...fontStyle(theme, 600), color: c.fg, letterSpacing: -0.2 };
|
|
27
|
+
return {
|
|
28
|
+
body,
|
|
29
|
+
paragraph: { marginTop: 0, marginBottom: 10 },
|
|
30
|
+
// Web margins collapse against the 10pt paragraph margin; native margins add up.
|
|
31
|
+
heading1: { ...heading, fontSize: 20, lineHeight: 28, marginTop: 10, marginBottom: 10 },
|
|
32
|
+
heading2: { ...heading, fontSize: 18, lineHeight: 26, marginTop: 10, marginBottom: 8 },
|
|
33
|
+
heading3: {
|
|
34
|
+
...heading,
|
|
35
|
+
fontSize: theme.size.md,
|
|
36
|
+
lineHeight: 24,
|
|
37
|
+
marginTop: 6,
|
|
38
|
+
marginBottom: 6
|
|
39
|
+
},
|
|
40
|
+
heading4: {
|
|
41
|
+
...heading,
|
|
42
|
+
fontSize: theme.size.sm,
|
|
43
|
+
lineHeight: 18,
|
|
44
|
+
marginTop: 6,
|
|
45
|
+
marginBottom: 6,
|
|
46
|
+
textTransform: "uppercase"
|
|
47
|
+
},
|
|
48
|
+
strong: { ...fontStyle(theme, 600), color: muted ? c["fg-muted"] : c.fg },
|
|
49
|
+
em: theme.fonts.sansItalic ? { fontFamily: theme.fonts.sansItalic } : { fontStyle: "italic" },
|
|
50
|
+
bullet_list: { marginTop: 0, marginBottom: 10 },
|
|
51
|
+
ordered_list: { marginTop: 0, marginBottom: 10 },
|
|
52
|
+
list_item: { marginBottom: 4 },
|
|
53
|
+
bullet_list_icon: { color: c["fg-subtle"], marginLeft: 6, marginRight: 8, lineHeight: line },
|
|
54
|
+
ordered_list_icon: { color: c["fg-subtle"], marginLeft: 2, marginRight: 6, lineHeight: line },
|
|
55
|
+
code_inline: {
|
|
56
|
+
...mono,
|
|
57
|
+
fontFamily: mono.fontFamily ?? MONO_FALLBACK,
|
|
58
|
+
fontSize: theme.size.sm,
|
|
59
|
+
backgroundColor: c["surface-2"],
|
|
60
|
+
color: c.fg,
|
|
61
|
+
borderRadius: theme.radius.xs,
|
|
62
|
+
paddingHorizontal: 4,
|
|
63
|
+
borderWidth: 0
|
|
64
|
+
},
|
|
65
|
+
fence: {
|
|
66
|
+
...mono,
|
|
67
|
+
fontSize: theme.size.sm,
|
|
68
|
+
lineHeight: 20,
|
|
69
|
+
color: c["fg-muted"],
|
|
70
|
+
backgroundColor: insetSurface(theme),
|
|
71
|
+
borderWidth: 0,
|
|
72
|
+
borderRadius: theme.radius.md,
|
|
73
|
+
paddingHorizontal: 12,
|
|
74
|
+
paddingVertical: 10,
|
|
75
|
+
marginTop: 2,
|
|
76
|
+
marginBottom: 10
|
|
77
|
+
},
|
|
78
|
+
code_block: {
|
|
79
|
+
...mono,
|
|
80
|
+
fontSize: theme.size.sm,
|
|
81
|
+
lineHeight: 20,
|
|
82
|
+
color: c["fg-muted"],
|
|
83
|
+
backgroundColor: insetSurface(theme),
|
|
84
|
+
borderWidth: 0,
|
|
85
|
+
borderRadius: theme.radius.md,
|
|
86
|
+
paddingHorizontal: 12,
|
|
87
|
+
paddingVertical: 10
|
|
88
|
+
},
|
|
89
|
+
// Web MARKDOWN_LINK_CLASS: medium weight in accent-strong, no underline.
|
|
90
|
+
link: {
|
|
91
|
+
...fontStyle(theme, 500),
|
|
92
|
+
color: c["accent-strong"],
|
|
93
|
+
textDecorationLine: "none"
|
|
94
|
+
},
|
|
95
|
+
blockquote: {
|
|
96
|
+
// Web blockquote text is fg-muted; text styles inherit through the renderer.
|
|
97
|
+
color: c["fg-muted"],
|
|
98
|
+
backgroundColor: "transparent",
|
|
99
|
+
borderLeftColor: c["border-strong"],
|
|
100
|
+
borderLeftWidth: 2,
|
|
101
|
+
paddingLeft: 14,
|
|
102
|
+
marginLeft: 0,
|
|
103
|
+
marginVertical: 12
|
|
104
|
+
},
|
|
105
|
+
hr: { backgroundColor: c.border, height: 1, marginVertical: 16 },
|
|
106
|
+
// Web tables: unboxed, text-og-base, hairline rules, content-sized columns.
|
|
107
|
+
table: { borderWidth: 0, marginTop: 12, marginBottom: 10 },
|
|
108
|
+
thead: {},
|
|
109
|
+
th: {
|
|
110
|
+
...fontStyle(theme, 500),
|
|
111
|
+
color: c.fg,
|
|
112
|
+
fontSize: theme.size.base,
|
|
113
|
+
lineHeight: 20,
|
|
114
|
+
paddingVertical: 6,
|
|
115
|
+
paddingRight: 16
|
|
116
|
+
},
|
|
117
|
+
tr: { borderBottomWidth: 0 },
|
|
118
|
+
td: {
|
|
119
|
+
color: c["fg-muted"],
|
|
120
|
+
fontSize: theme.size.base,
|
|
121
|
+
lineHeight: 20,
|
|
122
|
+
paddingVertical: 6,
|
|
123
|
+
paddingRight: 16
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function CodeFence({
|
|
128
|
+
content,
|
|
129
|
+
language,
|
|
130
|
+
onCopy
|
|
131
|
+
}) {
|
|
132
|
+
const theme = useNativeTimelineTheme();
|
|
133
|
+
const styles = webMarkdownStyles(theme, "body");
|
|
134
|
+
const [copied, setCopied] = useState(false);
|
|
135
|
+
const [chromeWidth, setChromeWidth] = useState(64);
|
|
136
|
+
return /* @__PURE__ */ jsxs(View, { style: { marginTop: 2, marginBottom: 10 }, children: [
|
|
137
|
+
/* @__PURE__ */ jsx(
|
|
138
|
+
View,
|
|
139
|
+
{
|
|
140
|
+
style: {
|
|
141
|
+
borderRadius: theme.radius.md,
|
|
142
|
+
backgroundColor: insetSurface(theme),
|
|
143
|
+
paddingLeft: 12,
|
|
144
|
+
paddingRight: chromeWidth,
|
|
145
|
+
paddingVertical: 10
|
|
146
|
+
},
|
|
147
|
+
children: /* @__PURE__ */ jsx(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, children: /* @__PURE__ */ jsx(
|
|
148
|
+
Text,
|
|
149
|
+
{
|
|
150
|
+
selectable: true,
|
|
151
|
+
style: {
|
|
152
|
+
...styles.code_block,
|
|
153
|
+
backgroundColor: "transparent",
|
|
154
|
+
paddingHorizontal: 0,
|
|
155
|
+
paddingVertical: 0
|
|
156
|
+
},
|
|
157
|
+
children: content
|
|
158
|
+
}
|
|
159
|
+
) })
|
|
160
|
+
}
|
|
161
|
+
),
|
|
162
|
+
/* @__PURE__ */ jsxs(
|
|
163
|
+
View,
|
|
164
|
+
{
|
|
165
|
+
onLayout: (event) => {
|
|
166
|
+
const next = Math.ceil(event.nativeEvent.layout.width) + 6 + 10;
|
|
167
|
+
if (next !== chromeWidth) setChromeWidth(next);
|
|
168
|
+
},
|
|
169
|
+
style: {
|
|
170
|
+
position: "absolute",
|
|
171
|
+
top: 6,
|
|
172
|
+
right: 6,
|
|
173
|
+
flexDirection: "row",
|
|
174
|
+
alignItems: "center",
|
|
175
|
+
gap: 4
|
|
176
|
+
},
|
|
177
|
+
children: [
|
|
178
|
+
language ? /* @__PURE__ */ jsx(
|
|
179
|
+
Text,
|
|
180
|
+
{
|
|
181
|
+
style: {
|
|
182
|
+
...fontStyle(theme, 400, "mono"),
|
|
183
|
+
fontSize: 10,
|
|
184
|
+
letterSpacing: 0.5,
|
|
185
|
+
textTransform: "uppercase",
|
|
186
|
+
color: theme.colors["fg-subtle"],
|
|
187
|
+
opacity: 0.7
|
|
188
|
+
},
|
|
189
|
+
children: language
|
|
190
|
+
}
|
|
191
|
+
) : null,
|
|
192
|
+
onCopy ? /* @__PURE__ */ jsx(
|
|
193
|
+
Pressable,
|
|
194
|
+
{
|
|
195
|
+
accessibilityRole: "button",
|
|
196
|
+
accessibilityLabel: "Copy code",
|
|
197
|
+
hitSlop: 8,
|
|
198
|
+
onPress: () => {
|
|
199
|
+
onCopy(content);
|
|
200
|
+
setCopied(true);
|
|
201
|
+
setTimeout(() => setCopied(false), 1400);
|
|
202
|
+
},
|
|
203
|
+
style: { width: 28, height: 28, alignItems: "center", justifyContent: "center" },
|
|
204
|
+
children: /* @__PURE__ */ jsx(Icon, { name: copied ? "check" : "copy", size: 14, color: theme.colors["fg-subtle"] })
|
|
205
|
+
}
|
|
206
|
+
) : null
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
)
|
|
210
|
+
] });
|
|
211
|
+
}
|
|
212
|
+
function astText(node) {
|
|
213
|
+
if (node.children && node.children.length > 0) return node.children.map(astText).join("");
|
|
214
|
+
return typeof node.content === "string" ? node.content : "";
|
|
215
|
+
}
|
|
216
|
+
function tableRows(table) {
|
|
217
|
+
const rows = [];
|
|
218
|
+
const visit = (node) => {
|
|
219
|
+
if (node.type === "tr") rows.push((node.children ?? []).map((cell) => astText(cell).trim()));
|
|
220
|
+
else (node.children ?? []).forEach(visit);
|
|
221
|
+
};
|
|
222
|
+
visit(table);
|
|
223
|
+
return rows;
|
|
224
|
+
}
|
|
225
|
+
function tableColumns(rows) {
|
|
226
|
+
const count = Math.max(0, ...rows.map((row) => row.length));
|
|
227
|
+
return Array.from({ length: count }, (_, index) => {
|
|
228
|
+
const longest = Math.max(1, ...rows.map((row) => row[index]?.length ?? 0));
|
|
229
|
+
return longest <= 14 ? { width: Math.ceil(longest * 8.4) + 20, grow: 0 } : { grow: longest };
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
function cellIndex(node) {
|
|
233
|
+
return typeof node.index === "number" && node.index >= 0 ? node.index : 0;
|
|
234
|
+
}
|
|
235
|
+
var TableColumnsContext = createContext([]);
|
|
236
|
+
function columnWidths(columns, available) {
|
|
237
|
+
const fixed = columns.reduce((sum, column) => sum + (column.width ?? 0), 0);
|
|
238
|
+
const growth = columns.reduce(
|
|
239
|
+
(sum, column) => sum + (column.width === void 0 ? column.grow : 0),
|
|
240
|
+
0
|
|
241
|
+
);
|
|
242
|
+
const rest = Math.max(0, available - fixed);
|
|
243
|
+
if (growth === 0) return columns.map((column) => column.width ?? 0);
|
|
244
|
+
return columns.map(
|
|
245
|
+
(column) => column.width !== void 0 ? column.width : Math.max(64, rest * column.grow / growth)
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
function MarkdownTable({
|
|
249
|
+
node,
|
|
250
|
+
children,
|
|
251
|
+
onCopy
|
|
252
|
+
}) {
|
|
253
|
+
const theme = useNativeTimelineTheme();
|
|
254
|
+
const rows = useMemo(() => tableRows(node), [node]);
|
|
255
|
+
const columns = useMemo(() => tableColumns(rows), [rows]);
|
|
256
|
+
const [available, setAvailable] = useState(0);
|
|
257
|
+
const widths = useMemo(
|
|
258
|
+
() => available > 0 ? columnWidths(columns, available) : [],
|
|
259
|
+
[available, columns]
|
|
260
|
+
);
|
|
261
|
+
const [copied, setCopied] = useState(false);
|
|
262
|
+
return /* @__PURE__ */ jsxs(
|
|
263
|
+
View,
|
|
264
|
+
{
|
|
265
|
+
style: { marginTop: 12, marginBottom: 10 },
|
|
266
|
+
onLayout: (event) => setAvailable(Math.round(event.nativeEvent.layout.width)),
|
|
267
|
+
children: [
|
|
268
|
+
/* @__PURE__ */ jsx(TableColumnsContext.Provider, { value: widths, children }),
|
|
269
|
+
onCopy ? /* @__PURE__ */ jsx(
|
|
270
|
+
Pressable,
|
|
271
|
+
{
|
|
272
|
+
accessibilityRole: "button",
|
|
273
|
+
accessibilityLabel: "Copy table",
|
|
274
|
+
hitSlop: 8,
|
|
275
|
+
onPress: () => {
|
|
276
|
+
onCopy(rows.map((row) => row.join(" ")).join("\n"));
|
|
277
|
+
setCopied(true);
|
|
278
|
+
setTimeout(() => setCopied(false), 1400);
|
|
279
|
+
},
|
|
280
|
+
style: {
|
|
281
|
+
position: "absolute",
|
|
282
|
+
top: 2,
|
|
283
|
+
right: 0,
|
|
284
|
+
width: 28,
|
|
285
|
+
height: 28,
|
|
286
|
+
alignItems: "center",
|
|
287
|
+
justifyContent: "center"
|
|
288
|
+
},
|
|
289
|
+
children: /* @__PURE__ */ jsx(Icon, { name: copied ? "check" : "copy", size: 14, color: theme.colors["fg-subtle"] })
|
|
290
|
+
}
|
|
291
|
+
) : null
|
|
292
|
+
]
|
|
293
|
+
}
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
function TableRow({ head, last, children }) {
|
|
297
|
+
const theme = useNativeTimelineTheme();
|
|
298
|
+
const c = theme.colors;
|
|
299
|
+
return /* @__PURE__ */ jsx(
|
|
300
|
+
View,
|
|
301
|
+
{
|
|
302
|
+
style: {
|
|
303
|
+
flexDirection: "row",
|
|
304
|
+
borderBottomWidth: last ? 0 : 1,
|
|
305
|
+
// Header rule in border; body rules at 70% (web border-og-border/70).
|
|
306
|
+
borderBottomColor: head ? c.border : withAlpha(c.border, 0.7)
|
|
307
|
+
},
|
|
308
|
+
children
|
|
309
|
+
}
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
function TableCell({
|
|
313
|
+
index,
|
|
314
|
+
style,
|
|
315
|
+
children
|
|
316
|
+
}) {
|
|
317
|
+
const width = useContext(TableColumnsContext)[index];
|
|
318
|
+
return /* @__PURE__ */ jsx(
|
|
319
|
+
View,
|
|
320
|
+
{
|
|
321
|
+
style: [
|
|
322
|
+
style,
|
|
323
|
+
// The renderer's default cell style is flex: 1 (equal columns); a measured
|
|
324
|
+
// table replaces it with content-sized widths.
|
|
325
|
+
width !== void 0 ? { flex: 0, width } : null
|
|
326
|
+
],
|
|
327
|
+
children
|
|
328
|
+
}
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
function webRules(theme, tone, onCopy) {
|
|
332
|
+
const line = tone === "muted" ? 24 : 28;
|
|
333
|
+
return {
|
|
334
|
+
...renderRules,
|
|
335
|
+
// Web lists use a disc marker in fg-subtle; the library's iOS default is a middle dot.
|
|
336
|
+
list_item: (node, children, parent, styles, inheritedStyles = {}) => {
|
|
337
|
+
if (parent.some((entry) => entry.type === "bullet_list")) {
|
|
338
|
+
const disc = 5.5;
|
|
339
|
+
return /* @__PURE__ */ jsxs(View, { style: { flexDirection: "row", marginBottom: 4 }, children: [
|
|
340
|
+
/* @__PURE__ */ jsx(
|
|
341
|
+
View,
|
|
342
|
+
{
|
|
343
|
+
accessible: false,
|
|
344
|
+
style: { width: 20, height: line, alignItems: "center", justifyContent: "center" },
|
|
345
|
+
children: /* @__PURE__ */ jsx(
|
|
346
|
+
View,
|
|
347
|
+
{
|
|
348
|
+
style: {
|
|
349
|
+
width: disc,
|
|
350
|
+
height: disc,
|
|
351
|
+
borderRadius: disc / 2,
|
|
352
|
+
backgroundColor: theme.colors["fg-subtle"]
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
)
|
|
356
|
+
}
|
|
357
|
+
),
|
|
358
|
+
/* @__PURE__ */ jsx(View, { style: { flex: 1, minWidth: 0 }, children })
|
|
359
|
+
] }, node.key);
|
|
360
|
+
}
|
|
361
|
+
return renderRules.list_item(node, children, parent, styles, inheritedStyles);
|
|
362
|
+
},
|
|
363
|
+
table: (node, children) => /* @__PURE__ */ jsx(MarkdownTable, { node, onCopy, children }, node.key),
|
|
364
|
+
tr: (node, children, parent) => {
|
|
365
|
+
const head = parent.some((entry) => entry.type === "thead");
|
|
366
|
+
const body = parent.find((entry) => entry.type === "tbody");
|
|
367
|
+
const last = !head && body?.children?.[body.children.length - 1] === node;
|
|
368
|
+
return /* @__PURE__ */ jsx(TableRow, { head, last, children }, node.key);
|
|
369
|
+
},
|
|
370
|
+
th: (node, children, _parent, styles) => /* @__PURE__ */ jsx(TableCell, { index: cellIndex(node), style: styles._VIEW_SAFE_th, children }, node.key),
|
|
371
|
+
td: (node, children, _parent, styles) => /* @__PURE__ */ jsx(TableCell, { index: cellIndex(node), style: styles._VIEW_SAFE_td, children }, node.key),
|
|
372
|
+
fence: (node) => {
|
|
373
|
+
const raw = typeof node.content === "string" ? node.content : "";
|
|
374
|
+
const content = raw.endsWith("\n") ? raw.slice(0, -1) : raw;
|
|
375
|
+
const info = node.sourceInfo;
|
|
376
|
+
const language = typeof info === "string" ? info.trim().split(/\s+/)[0] ?? "" : "";
|
|
377
|
+
return /* @__PURE__ */ jsx(CodeFence, { content, language, onCopy }, node.key);
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
function TrimmedMarkdown({
|
|
382
|
+
text,
|
|
383
|
+
tone,
|
|
384
|
+
onLinkPress,
|
|
385
|
+
onCopy
|
|
386
|
+
}) {
|
|
387
|
+
const theme = useNativeTimelineTheme();
|
|
388
|
+
const styles = useMemo(() => webMarkdownStyles(theme, tone), [theme, tone]);
|
|
389
|
+
const rules = useMemo(() => webRules(theme, tone, onCopy), [theme, tone, onCopy]);
|
|
390
|
+
return /* @__PURE__ */ jsx(View, { style: { marginBottom: -10 }, children: /* @__PURE__ */ jsx(
|
|
391
|
+
Markdown,
|
|
392
|
+
{
|
|
393
|
+
markdownit: PARSER,
|
|
394
|
+
style: styles,
|
|
395
|
+
rules,
|
|
396
|
+
...onLinkPress ? { onLinkPress } : {},
|
|
397
|
+
children: text
|
|
398
|
+
}
|
|
399
|
+
) });
|
|
400
|
+
}
|
|
401
|
+
function createWebMarkdownRenderer(options = {}) {
|
|
402
|
+
const onLinkPress = (url) => {
|
|
403
|
+
const target = parseOpenGeniLink(url);
|
|
404
|
+
if (target || isReservedOpenGeniLink(url)) {
|
|
405
|
+
if (target) options.onOpenGeniLink?.(target);
|
|
406
|
+
return false;
|
|
407
|
+
}
|
|
408
|
+
return options.onLinkPress ? options.onLinkPress(url) : true;
|
|
409
|
+
};
|
|
410
|
+
return (text, { tone }) => text.trim() ? /* @__PURE__ */ jsx(TrimmedMarkdown, { text, tone, onLinkPress, onCopy: options.onCopy }) : /* @__PURE__ */ jsx(Text, {});
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
export { createWebMarkdownRenderer, webMarkdownStyles };
|
|
414
|
+
//# sourceMappingURL=markdown.js.map
|
|
415
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/timeline/markdown.tsx"],"names":[],"mappings":"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","file":"markdown.js","sourcesContent":["import { createContext, useContext, useMemo, useState, type ReactNode } from \"react\";\nimport { Pressable, ScrollView, Text, View, type TextStyle } from \"react-native\";\nimport Markdown, { MarkdownIt, renderRules, type RenderRules } from \"react-native-markdown-display\";\nimport { isReservedOpenGeniLink, parseOpenGeniLink, type OpenGeniLinkTarget } from \"@opengeni/sdk\";\nimport { Icon } from \"./icon\";\nimport { withAlpha as withAlphaColor } from \"./primitives\";\nimport type { NativeMarkdownRenderer } from \"./message-timeline\";\nimport {\n fontStyle,\n insetSurface,\n MONO_FALLBACK,\n useNativeTimelineTheme,\n type NativeTimelineTheme,\n} from \"./theme\";\n\n/**\n * One parser for every message, configured like the web's `remark-gfm`: no typographic\n * substitution (quotes, dashes and `(c)` stay as written), and bare `http(s)://` URLs\n * autolink while file-like words (`fib.py`) do not. The library default would build a\n * new typographer parser on every render, including every streaming delta.\n */\nconst PARSER = (() => {\n const parser = MarkdownIt({ typographer: false, linkify: true });\n parser.linkify.set({ fuzzyLink: false, fuzzyEmail: false });\n return parser;\n})();\n\n/* ----------------------------------------------------------------------------\n Web Markdown (components/markdown.tsx) styles for react-native-markdown-display.\n Prose 15/28 (`text-og-md leading-7`), paragraphs `my-2.5`, lists `ml-5 gap-1`,\n code blocks `rounded-og-md bg-surface-1/70 px-3 py-2.5 text-og-sm leading-5`.\n -------------------------------------------------------------------------- */\n\nexport function webMarkdownStyles(\n theme: NativeTimelineTheme,\n tone: \"body\" | \"muted\",\n): Record<string, TextStyle> {\n const c = theme.colors;\n const muted = tone === \"muted\";\n const size = muted ? theme.size.base : theme.size.md;\n const line = muted ? 24 : 28;\n const body = {\n ...fontStyle(theme),\n color: muted ? c[\"fg-muted\"] : c.fg,\n fontSize: size,\n lineHeight: line,\n };\n const mono = fontStyle(theme, 400, \"mono\");\n const heading = { ...fontStyle(theme, 600), color: c.fg, letterSpacing: -0.2 };\n return {\n body,\n paragraph: { marginTop: 0, marginBottom: 10 },\n // Web margins collapse against the 10pt paragraph margin; native margins add up.\n heading1: { ...heading, fontSize: 20, lineHeight: 28, marginTop: 10, marginBottom: 10 },\n heading2: { ...heading, fontSize: 18, lineHeight: 26, marginTop: 10, marginBottom: 8 },\n heading3: {\n ...heading,\n fontSize: theme.size.md,\n lineHeight: 24,\n marginTop: 6,\n marginBottom: 6,\n },\n heading4: {\n ...heading,\n fontSize: theme.size.sm,\n lineHeight: 18,\n marginTop: 6,\n marginBottom: 6,\n textTransform: \"uppercase\" as const,\n },\n strong: { ...fontStyle(theme, 600), color: muted ? c[\"fg-muted\"] : c.fg },\n em: theme.fonts.sansItalic\n ? { fontFamily: theme.fonts.sansItalic }\n : { fontStyle: \"italic\" as const },\n bullet_list: { marginTop: 0, marginBottom: 10 },\n ordered_list: { marginTop: 0, marginBottom: 10 },\n list_item: { marginBottom: 4 },\n bullet_list_icon: { color: c[\"fg-subtle\"], marginLeft: 6, marginRight: 8, lineHeight: line },\n ordered_list_icon: { color: c[\"fg-subtle\"], marginLeft: 2, marginRight: 6, lineHeight: line },\n code_inline: {\n ...mono,\n fontFamily: (mono.fontFamily as string | undefined) ?? MONO_FALLBACK,\n fontSize: theme.size.sm,\n backgroundColor: c[\"surface-2\"],\n color: c.fg,\n borderRadius: theme.radius.xs,\n paddingHorizontal: 4,\n borderWidth: 0,\n },\n fence: {\n ...mono,\n fontSize: theme.size.sm,\n lineHeight: 20,\n color: c[\"fg-muted\"],\n backgroundColor: insetSurface(theme),\n borderWidth: 0,\n borderRadius: theme.radius.md,\n paddingHorizontal: 12,\n paddingVertical: 10,\n marginTop: 2,\n marginBottom: 10,\n },\n code_block: {\n ...mono,\n fontSize: theme.size.sm,\n lineHeight: 20,\n color: c[\"fg-muted\"],\n backgroundColor: insetSurface(theme),\n borderWidth: 0,\n borderRadius: theme.radius.md,\n paddingHorizontal: 12,\n paddingVertical: 10,\n },\n // Web MARKDOWN_LINK_CLASS: medium weight in accent-strong, no underline.\n link: {\n ...fontStyle(theme, 500),\n color: c[\"accent-strong\"],\n textDecorationLine: \"none\" as const,\n },\n blockquote: {\n // Web blockquote text is fg-muted; text styles inherit through the renderer.\n color: c[\"fg-muted\"],\n backgroundColor: \"transparent\",\n borderLeftColor: c[\"border-strong\"],\n borderLeftWidth: 2,\n paddingLeft: 14,\n marginLeft: 0,\n marginVertical: 12,\n },\n hr: { backgroundColor: c.border, height: 1, marginVertical: 16 },\n // Web tables: unboxed, text-og-base, hairline rules, content-sized columns.\n table: { borderWidth: 0, marginTop: 12, marginBottom: 10 },\n thead: {},\n th: {\n ...fontStyle(theme, 500),\n color: c.fg,\n fontSize: theme.size.base,\n lineHeight: 20,\n paddingVertical: 6,\n paddingRight: 16,\n },\n tr: { borderBottomWidth: 0 },\n td: {\n color: c[\"fg-muted\"],\n fontSize: theme.size.base,\n lineHeight: 20,\n paddingVertical: 6,\n paddingRight: 16,\n },\n };\n}\n\nfunction CodeFence({\n content,\n language,\n onCopy,\n}: {\n content: string;\n language: string;\n onCopy?: ((text: string) => void) | undefined;\n}) {\n const theme = useNativeTimelineTheme();\n const styles = webMarkdownStyles(theme, \"body\");\n const [copied, setCopied] = useState(false);\n // The code scrolls in the space left of the language label and copy button, which\n // vary in width (\"SH\" vs \"TYPESCRIPT\"); reserve their measured width plus a gap.\n const [chromeWidth, setChromeWidth] = useState(64);\n return (\n <View style={{ marginTop: 2, marginBottom: 10 }}>\n <View\n style={{\n borderRadius: theme.radius.md,\n backgroundColor: insetSurface(theme),\n paddingLeft: 12,\n paddingRight: chromeWidth,\n paddingVertical: 10,\n }}\n >\n <ScrollView horizontal showsHorizontalScrollIndicator={false}>\n <Text\n selectable\n style={{\n ...styles.code_block,\n backgroundColor: \"transparent\",\n paddingHorizontal: 0,\n paddingVertical: 0,\n }}\n >\n {content}\n </Text>\n </ScrollView>\n </View>\n <View\n onLayout={(event) => {\n const next = Math.ceil(event.nativeEvent.layout.width) + 6 + 10;\n if (next !== chromeWidth) setChromeWidth(next);\n }}\n style={{\n position: \"absolute\",\n top: 6,\n right: 6,\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: 4,\n }}\n >\n {language ? (\n <Text\n style={{\n ...fontStyle(theme, 400, \"mono\"),\n fontSize: 10,\n letterSpacing: 0.5,\n textTransform: \"uppercase\",\n color: theme.colors[\"fg-subtle\"],\n opacity: 0.7,\n }}\n >\n {language}\n </Text>\n ) : null}\n {onCopy ? (\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel=\"Copy code\"\n hitSlop={8}\n onPress={() => {\n onCopy(content);\n setCopied(true);\n setTimeout(() => setCopied(false), 1400);\n }}\n style={{ width: 28, height: 28, alignItems: \"center\", justifyContent: \"center\" }}\n >\n <Icon name={copied ? \"check\" : \"copy\"} size={14} color={theme.colors[\"fg-subtle\"]} />\n </Pressable>\n ) : null}\n </View>\n </View>\n );\n}\n\n/* Tables ------------------------------------------------------------------- */\n\ntype AstNode = { type: string; content?: string; children?: AstNode[] };\n\nfunction astText(node: AstNode): string {\n // Container nodes carry an empty content string; text lives in their leaves.\n if (node.children && node.children.length > 0) return node.children.map(astText).join(\"\");\n return typeof node.content === \"string\" ? node.content : \"\";\n}\n\nfunction tableRows(table: AstNode): string[][] {\n const rows: string[][] = [];\n const visit = (node: AstNode) => {\n if (node.type === \"tr\") rows.push((node.children ?? []).map((cell) => astText(cell).trim()));\n else (node.children ?? []).forEach(visit);\n };\n visit(table);\n return rows;\n}\n\n/**\n * Content-sized columns, as a browser's auto table layout lays them out: short\n * columns keep their natural width on one line, long ones share the rest.\n */\nfunction tableColumns(rows: string[][]): { width?: number; grow: number }[] {\n const count = Math.max(0, ...rows.map((row) => row.length));\n return Array.from({ length: count }, (_, index) => {\n const longest = Math.max(1, ...rows.map((row) => row[index]?.length ?? 0));\n return longest <= 14 ? { width: Math.ceil(longest * 8.4) + 20, grow: 0 } : { grow: longest };\n });\n}\n\n/** A cell's column: its sibling index in the row (set by the AST builder). */\nfunction cellIndex(node: { index?: unknown }): number {\n return typeof node.index === \"number\" && node.index >= 0 ? node.index : 0;\n}\n\n/** Explicit column widths for a measured table; empty until the table lays out. */\nconst TableColumnsContext = createContext<number[]>([]);\n\nfunction columnWidths(columns: { width?: number; grow: number }[], available: number): number[] {\n const fixed = columns.reduce((sum, column) => sum + (column.width ?? 0), 0);\n const growth = columns.reduce(\n (sum, column) => sum + (column.width === undefined ? column.grow : 0),\n 0,\n );\n const rest = Math.max(0, available - fixed);\n if (growth === 0) return columns.map((column) => column.width ?? 0);\n // Long columns share the rest by length, each keeping a readable minimum.\n return columns.map((column) =>\n column.width !== undefined ? column.width : Math.max(64, (rest * column.grow) / growth),\n );\n}\n\nfunction MarkdownTable({\n node,\n children,\n onCopy,\n}: {\n node: AstNode;\n children: ReactNode;\n onCopy?: ((text: string) => void) | undefined;\n}) {\n const theme = useNativeTimelineTheme();\n const rows = useMemo(() => tableRows(node), [node]);\n const columns = useMemo(() => tableColumns(rows), [rows]);\n const [available, setAvailable] = useState(0);\n const widths = useMemo(\n () => (available > 0 ? columnWidths(columns, available) : []),\n [available, columns],\n );\n const [copied, setCopied] = useState(false);\n return (\n <View\n style={{ marginTop: 12, marginBottom: 10 }}\n onLayout={(event) => setAvailable(Math.round(event.nativeEvent.layout.width))}\n >\n <TableColumnsContext.Provider value={widths}>{children}</TableColumnsContext.Provider>\n {onCopy ? (\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel=\"Copy table\"\n hitSlop={8}\n onPress={() => {\n onCopy(rows.map((row) => row.join(\"\\t\")).join(\"\\n\"));\n setCopied(true);\n setTimeout(() => setCopied(false), 1400);\n }}\n style={{\n position: \"absolute\",\n top: 2,\n right: 0,\n width: 28,\n height: 28,\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <Icon name={copied ? \"check\" : \"copy\"} size={14} color={theme.colors[\"fg-subtle\"]} />\n </Pressable>\n ) : null}\n </View>\n );\n}\n\nfunction TableRow({ head, last, children }: { head: boolean; last: boolean; children: ReactNode }) {\n const theme = useNativeTimelineTheme();\n const c = theme.colors;\n return (\n <View\n style={{\n flexDirection: \"row\",\n borderBottomWidth: last ? 0 : 1,\n // Header rule in border; body rules at 70% (web border-og-border/70).\n borderBottomColor: head ? c.border : withAlphaColor(c.border, 0.7),\n }}\n >\n {children}\n </View>\n );\n}\n\nfunction TableCell({\n index,\n style,\n children,\n}: {\n index: number;\n style: object;\n children: ReactNode;\n}) {\n const width = useContext(TableColumnsContext)[index];\n return (\n <View\n style={[\n style,\n // The renderer's default cell style is flex: 1 (equal columns); a measured\n // table replaces it with content-sized widths.\n width !== undefined ? { flex: 0, width } : null,\n ]}\n >\n {children}\n </View>\n );\n}\n\nfunction webRules(\n theme: NativeTimelineTheme,\n tone: \"body\" | \"muted\",\n onCopy?: (text: string) => void,\n): RenderRules {\n const line = tone === \"muted\" ? 24 : 28;\n return {\n ...renderRules,\n // Web lists use a disc marker in fg-subtle; the library's iOS default is a middle dot.\n list_item: (node, children, parent, styles, inheritedStyles = {}) => {\n if (parent.some((entry: { type: string }) => entry.type === \"bullet_list\")) {\n // A drawn disc: the text bullet glyph renders noticeably smaller than\n // the browser's list-disc marker at the same line height.\n const disc = 5.5;\n return (\n <View key={node.key} style={{ flexDirection: \"row\", marginBottom: 4 }}>\n <View\n accessible={false}\n style={{ width: 20, height: line, alignItems: \"center\", justifyContent: \"center\" }}\n >\n <View\n style={{\n width: disc,\n height: disc,\n borderRadius: disc / 2,\n backgroundColor: theme.colors[\"fg-subtle\"],\n }}\n />\n </View>\n <View style={{ flex: 1, minWidth: 0 }}>{children}</View>\n </View>\n );\n }\n return renderRules.list_item!(node, children, parent, styles, inheritedStyles);\n },\n table: (node, children) => (\n <MarkdownTable key={node.key} node={node} onCopy={onCopy}>\n {children}\n </MarkdownTable>\n ),\n tr: (node, children, parent) => {\n const head = parent.some((entry: { type: string }) => entry.type === \"thead\");\n const body = parent.find((entry: { type: string }) => entry.type === \"tbody\") as\n | { children?: unknown[] }\n | undefined;\n const last = !head && body?.children?.[body.children.length - 1] === node;\n return (\n <TableRow key={node.key} head={head} last={last}>\n {children}\n </TableRow>\n );\n },\n th: (node, children, _parent, styles) => (\n <TableCell key={node.key} index={cellIndex(node)} style={styles._VIEW_SAFE_th}>\n {children}\n </TableCell>\n ),\n td: (node, children, _parent, styles) => (\n <TableCell key={node.key} index={cellIndex(node)} style={styles._VIEW_SAFE_td}>\n {children}\n </TableCell>\n ),\n fence: (node) => {\n const raw = typeof node.content === \"string\" ? node.content : \"\";\n const content = raw.endsWith(\"\\n\") ? raw.slice(0, -1) : raw;\n const info = (node as { sourceInfo?: unknown }).sourceInfo;\n const language = typeof info === \"string\" ? (info.trim().split(/\\s+/)[0] ?? \"\") : \"\";\n return <CodeFence key={node.key} content={content} language={language} onCopy={onCopy} />;\n },\n };\n}\n\n/** Trim the trailing paragraph margin (web `last:mb-0`). */\nfunction TrimmedMarkdown({\n text,\n tone,\n onLinkPress,\n onCopy,\n}: {\n text: string;\n tone: \"body\" | \"muted\";\n onLinkPress?: ((url: string) => boolean) | undefined;\n onCopy?: ((text: string) => void) | undefined;\n}) {\n const theme = useNativeTimelineTheme();\n const styles = useMemo(() => webMarkdownStyles(theme, tone), [theme, tone]);\n const rules = useMemo(() => webRules(theme, tone, onCopy), [theme, tone, onCopy]);\n return (\n <View style={{ marginBottom: -10 }}>\n <Markdown\n markdownit={PARSER}\n style={styles}\n rules={rules}\n {...(onLinkPress ? { onLinkPress } : {})}\n >\n {text}\n </Markdown>\n </View>\n );\n}\n\nexport function createWebMarkdownRenderer(\n options: {\n onLinkPress?: (url: string) => boolean;\n onCopy?: (text: string) => void;\n /** OpenGeni links (sandbox files, artifacts, Sites); never handed to the OS. */\n onOpenGeniLink?: (target: OpenGeniLinkTarget) => void;\n } = {},\n): NativeMarkdownRenderer {\n const onLinkPress = (url: string): boolean => {\n const target = parseOpenGeniLink(url);\n if (target || isReservedOpenGeniLink(url)) {\n if (target) options.onOpenGeniLink?.(target);\n return false;\n }\n return options.onLinkPress ? options.onLinkPress(url) : true;\n };\n return (text, { tone }): ReactNode =>\n text.trim() ? (\n <TrimmedMarkdown text={text} tone={tone} onLinkPress={onLinkPress} onCopy={options.onCopy} />\n ) : (\n <Text />\n );\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { OpenGeniClient, ResourceRef } from "@opengeni/sdk";
|
|
2
|
+
type AttachmentClient = Pick<OpenGeniClient, "getFile" | "createFileDownloadUrl">;
|
|
3
|
+
/**
|
|
4
|
+
* Files sent with a user message, above its bubble as on web: images as
|
|
5
|
+
* signed previews (tap opens the full image), other files as named chips.
|
|
6
|
+
*/
|
|
7
|
+
export declare function NativeMessageAttachments(props: {
|
|
8
|
+
client: AttachmentClient;
|
|
9
|
+
workspaceId: string;
|
|
10
|
+
sessionId?: string | undefined;
|
|
11
|
+
resources: readonly ResourceRef[];
|
|
12
|
+
}): import("react").JSX.Element | null;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { SessionEvent, SessionStatus } from "@opengeni/sdk";
|
|
2
|
+
import { type AgentMessageItem, type TimelineItem, type UserMessageItem } from "@opengeni/react/session";
|
|
3
|
+
import { type TurnSummaryFacetConfiguration } from "@opengeni/react/timeline-model";
|
|
4
|
+
import { type ReactNode } from "react";
|
|
5
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
6
|
+
import { type NativeActivityOptions } from "./activity.js";
|
|
7
|
+
import { type PreparingProps } from "./turn.js";
|
|
8
|
+
export type NativeMarkdownRenderer = (text: string, options: {
|
|
9
|
+
tone: "body" | "muted";
|
|
10
|
+
streaming?: boolean | undefined;
|
|
11
|
+
}) => ReactNode;
|
|
12
|
+
export interface NativeMessageTimelineProps extends NativeActivityOptions {
|
|
13
|
+
/** Projected items (preferred) or raw durable events. */
|
|
14
|
+
items?: TimelineItem[] | undefined;
|
|
15
|
+
events?: SessionEvent[] | undefined;
|
|
16
|
+
status?: SessionStatus | null | undefined;
|
|
17
|
+
facets?: TurnSummaryFacetConfiguration | undefined;
|
|
18
|
+
renderMarkdown?: NativeMarkdownRenderer | undefined;
|
|
19
|
+
/** Replace the preparing visual (the web orb) — e.g. a product character. */
|
|
20
|
+
renderPreparing?: ((props: PreparingProps) => ReactNode) | undefined;
|
|
21
|
+
/** Extra actions beside copy under a message (feedback, share, …). */
|
|
22
|
+
renderMessageActions?: ((item: AgentMessageItem | UserMessageItem) => ReactNode) | undefined;
|
|
23
|
+
/** Files sent with a user message, shown above its bubble (images as previews). */
|
|
24
|
+
renderUserAttachments?: ((item: UserMessageItem) => ReactNode) | undefined;
|
|
25
|
+
onCopy?: ((text: string) => void) | undefined;
|
|
26
|
+
/** Rendered after the last group (pending questions, approvals, errors). */
|
|
27
|
+
trailing?: ReactNode;
|
|
28
|
+
emptyState?: ReactNode;
|
|
29
|
+
header?: ReactNode;
|
|
30
|
+
contentInsetTop?: number | undefined;
|
|
31
|
+
contentInsetBottom?: number | undefined;
|
|
32
|
+
/** Height of host chrome floating over the timeline's bottom edge (a floating composer). */
|
|
33
|
+
overlayInsetBottom?: number | undefined;
|
|
34
|
+
style?: StyleProp<ViewStyle>;
|
|
35
|
+
}
|
|
36
|
+
export declare function MessageTimeline(props: NativeMessageTimelineProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ClientModel, LatencyMode, ReasoningEffort } from "@opengeni/sdk";
|
|
2
|
+
import { type ModelPickerGroupPresentation, type ModelPickerInput } from "@opengeni/react/model-picker-model";
|
|
3
|
+
import { type ReactNode } from "react";
|
|
4
|
+
export type ModelPickerSheetProps = ModelPickerInput<ReactNode> & {
|
|
5
|
+
open: boolean;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
loading?: boolean | undefined;
|
|
8
|
+
error?: string | null | undefined;
|
|
9
|
+
disabled?: boolean | undefined;
|
|
10
|
+
onModelChange: (modelId: string) => void;
|
|
11
|
+
onEffortChange: (effort: ReasoningEffort) => void;
|
|
12
|
+
onLatencyModeChange: (mode: LatencyMode) => void;
|
|
13
|
+
/** Called after a choice, for host haptics. */
|
|
14
|
+
onSelectionFeedback?: (() => void) | undefined;
|
|
15
|
+
};
|
|
16
|
+
export declare function ModelPickerSheet(props: ModelPickerSheetProps): import("react").JSX.Element;
|
|
17
|
+
export type { ClientModel, ModelPickerGroupPresentation };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type TextStyle } from "react-native";
|
|
3
|
+
import { type NativeIconName } from "./icon.js";
|
|
4
|
+
import { type NativeTimelineTheme } from "./theme.js";
|
|
5
|
+
export declare const ReleaseFollowProvider: import("react").Provider<() => void>;
|
|
6
|
+
export declare function useReleaseFollow(): () => void;
|
|
7
|
+
export type DisclosureChip = {
|
|
8
|
+
tone: "ok" | "bad" | "muted" | "interrupted";
|
|
9
|
+
text: string;
|
|
10
|
+
};
|
|
11
|
+
export type IconTone = "accent" | "failed" | "running" | "muted";
|
|
12
|
+
export declare function iconToneColor(theme: NativeTimelineTheme, tone: IconTone): string;
|
|
13
|
+
/** Web `pointer-coarse:min-h-11`: every disclosure row is a 44pt touch target. */
|
|
14
|
+
export declare const ROW_MIN_HEIGHT = 44;
|
|
15
|
+
export declare function Chip({ chip }: {
|
|
16
|
+
chip: DisclosureChip;
|
|
17
|
+
}): import("react").JSX.Element;
|
|
18
|
+
/** The web `animate-og-pulse` dot that rides a running preview. */
|
|
19
|
+
export declare function PulseDot({ color, size }: {
|
|
20
|
+
color: string;
|
|
21
|
+
size?: number;
|
|
22
|
+
}): import("react").JSX.Element;
|
|
23
|
+
/**
|
|
24
|
+
* The web `og-shimmer-text` (a moving fg-subtle → fg → fg-subtle gradient) as an
|
|
25
|
+
* ink sweep between the same two tokens.
|
|
26
|
+
*/
|
|
27
|
+
export declare function ShimmerText({ children, style, active, numberOfLines, }: {
|
|
28
|
+
children: ReactNode;
|
|
29
|
+
style?: TextStyle | TextStyle[];
|
|
30
|
+
active?: boolean;
|
|
31
|
+
numberOfLines?: number;
|
|
32
|
+
}): import("react").JSX.Element;
|
|
33
|
+
export interface ActivityDisclosureProps {
|
|
34
|
+
icon: NativeIconName | ReactNode;
|
|
35
|
+
iconTone?: IconTone | undefined;
|
|
36
|
+
title: ReactNode;
|
|
37
|
+
titleMono?: boolean | undefined;
|
|
38
|
+
/** Title shimmer + preview pulse while in flight. */
|
|
39
|
+
running?: boolean | undefined;
|
|
40
|
+
preview?: ReactNode | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* A small trailing element (a thumbnail, an open action) shown in the right
|
|
43
|
+
* gutter in place of the preview and chip while collapsed, as on web.
|
|
44
|
+
*/
|
|
45
|
+
media?: ReactNode | undefined;
|
|
46
|
+
chip?: DisclosureChip | undefined;
|
|
47
|
+
failed?: boolean | undefined;
|
|
48
|
+
cancelled?: boolean | undefined;
|
|
49
|
+
expandable?: boolean | undefined;
|
|
50
|
+
defaultOpen?: boolean | undefined;
|
|
51
|
+
/** Compact reel rendering for the rolling status (no chevron, no body). */
|
|
52
|
+
compact?: boolean | undefined;
|
|
53
|
+
accessibilityLabel?: string | undefined;
|
|
54
|
+
children?: ReactNode | undefined;
|
|
55
|
+
}
|
|
56
|
+
/** The one row shape every activity uses, matching the web ActivityDisclosure. */
|
|
57
|
+
export declare function ActivityDisclosure({ icon, iconTone: iconToneProp, title, titleMono, running, preview, media, chip: chipProp, failed, cancelled, expandable, defaultOpen, compact, accessibilityLabel, children, }: ActivityDisclosureProps): import("react").JSX.Element;
|
|
58
|
+
/** A running preview: the pulse locus immediately left of the status words. */
|
|
59
|
+
export declare function RunningPreview({ text, compact }: {
|
|
60
|
+
text: string;
|
|
61
|
+
compact?: boolean;
|
|
62
|
+
}): import("react").JSX.Element;
|
|
63
|
+
export declare function TermBlock({ command, workdir, output, live, failed, tailLines, }: {
|
|
64
|
+
command: string | null;
|
|
65
|
+
workdir?: string | null | undefined;
|
|
66
|
+
output: string;
|
|
67
|
+
live?: boolean | undefined;
|
|
68
|
+
failed?: boolean | undefined;
|
|
69
|
+
tailLines?: number;
|
|
70
|
+
}): import("react").JSX.Element;
|
|
71
|
+
export declare function PayloadBlock({ label, value, failed, }: {
|
|
72
|
+
label: string;
|
|
73
|
+
value: unknown;
|
|
74
|
+
failed?: boolean | undefined;
|
|
75
|
+
}): import("react").JSX.Element | null;
|
|
76
|
+
export declare function BodyNote({ children, tone }: {
|
|
77
|
+
children: ReactNode;
|
|
78
|
+
tone?: "error" | undefined;
|
|
79
|
+
}): import("react").JSX.Element;
|
|
80
|
+
/**
|
|
81
|
+
* `color` at `alpha` composited over `base`, as an opaque color: a tinted
|
|
82
|
+
* surface that stays solid when it floats over scrolling content.
|
|
83
|
+
*/
|
|
84
|
+
export declare function blendOver(base: string, color: string, alpha: number): string;
|
|
85
|
+
export declare function withAlpha(color: string, alpha: number): string;
|