@adminide-stack/yantra-mobile 12.0.54-alpha.1 → 12.0.54-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/lib/components/CustomDrawer.js +28 -19
  2. package/lib/components/CustomDrawer.js.map +1 -1
  3. package/lib/components/NavigationHeader/HeaderMoreMenu.js +7 -4
  4. package/lib/components/NavigationHeader/HeaderMoreMenu.js.map +1 -1
  5. package/lib/components/NavigationHeader/HeaderSkillsButton.js +5 -2
  6. package/lib/components/NavigationHeader/HeaderSkillsButton.js.map +1 -1
  7. package/lib/components/NavigationHeader/HeaderTasksButton.js +4 -1
  8. package/lib/components/NavigationHeader/HeaderTasksButton.js.map +1 -1
  9. package/lib/components/NavigationHeader/NavigationHeader.js +7 -5
  10. package/lib/components/NavigationHeader/NavigationHeader.js.map +1 -1
  11. package/lib/compute.js +57 -7
  12. package/lib/compute.js.map +1 -1
  13. package/lib/features/agent-chat/NativeAgentChat.js +393 -0
  14. package/lib/features/agent-chat/NativeAgentChat.js.map +1 -0
  15. package/lib/features/apps/AppsCatalog.js +10 -0
  16. package/lib/features/apps/AppsCatalog.js.map +1 -1
  17. package/lib/features/apps/mobileAppCatalog.js +7 -0
  18. package/lib/features/apps/mobileAppCatalog.js.map +1 -1
  19. package/lib/features/attachments/displayUserMessageText.js +3 -2
  20. package/lib/features/attachments/displayUserMessageText.js.map +1 -1
  21. package/lib/features/attachments/useImageAttachments.js +9 -7
  22. package/lib/features/attachments/useImageAttachments.js.map +1 -1
  23. package/lib/features/canvas/withRemoteSafeArea.js +46 -0
  24. package/lib/features/canvas/withRemoteSafeArea.js.map +1 -0
  25. package/lib/features/chat/ChatTranscript.js +23 -15
  26. package/lib/features/chat/ChatTranscript.js.map +1 -1
  27. package/lib/features/chat/toolActivity.js +42 -6
  28. package/lib/features/chat/toolActivity.js.map +1 -1
  29. package/lib/features/chat/transcriptGroups.js +11 -2
  30. package/lib/features/chat/transcriptGroups.js.map +1 -1
  31. package/lib/features/shopping/chat/homeShoppingIntent.js +58 -0
  32. package/lib/features/shopping/chat/homeShoppingIntent.js.map +1 -0
  33. package/lib/features/shopping/chat/openShopNative.js +60 -0
  34. package/lib/features/shopping/chat/openShopNative.js.map +1 -0
  35. package/lib/features/travel/nativeTravelRegistry.js +15 -0
  36. package/lib/features/travel/nativeTravelRegistry.js.map +1 -0
  37. package/lib/graphql/typePolicies.js +35 -1
  38. package/lib/graphql/typePolicies.js.map +1 -1
  39. package/lib/hooks/useCdecliChannel.js +10 -8
  40. package/lib/hooks/useCdecliChannel.js.map +1 -1
  41. package/lib/hooks/useChatStream.js +13 -6
  42. package/lib/hooks/useChatStream.js.map +1 -1
  43. package/lib/index.js +1 -1
  44. package/lib/index.js.map +1 -1
  45. package/lib/routes.json +58 -3
  46. package/lib/screens/CanvasBoard/index.js +6 -1
  47. package/lib/screens/CanvasBoard/index.js.map +1 -1
  48. package/lib/screens/Chat/index.js +44 -5
  49. package/lib/screens/Chat/index.js.map +1 -1
  50. package/lib/screens/Home/HomeScreen.js +58 -21
  51. package/lib/screens/Home/HomeScreen.js.map +1 -1
  52. package/lib/screens/ShoppingNative/index.js +23 -2
  53. package/lib/screens/ShoppingNative/index.js.map +1 -1
  54. package/lib/screens/ShoppingNative/useShoppingHostChat.js +66 -0
  55. package/lib/screens/ShoppingNative/useShoppingHostChat.js.map +1 -0
  56. package/lib/screens/TravelNative/index.js +70 -0
  57. package/lib/screens/TravelNative/index.js.map +1 -0
  58. package/lib/screens/TravelNative/useTravelHostChat.js +66 -0
  59. package/lib/screens/TravelNative/useTravelHostChat.js.map +1 -0
  60. package/lib/services/brainQuickReply.js +72 -2
  61. package/lib/services/brainQuickReply.js.map +1 -1
  62. package/lib/utils/drawerNavigation.js +42 -0
  63. package/lib/utils/drawerNavigation.js.map +1 -0
  64. package/package.json +4 -4
@@ -0,0 +1,393 @@
1
+ import {jsxs,jsx,Fragment}from'react/jsx-runtime';import {useState,useRef,useEffect,useCallback,useMemo}from'react';import {StyleSheet,Keyboard,InteractionManager,PanResponder,View,KeyboardAvoidingView,Text,Pressable,ScrollView,Platform,TextInput,ActivityIndicator}from'react-native';import {dismissKeyboard}from'../../utils/keyboardController.js';import {MaterialCommunityIcons,Feather}from'@expo/vector-icons';import {useSafeInsets}from'../canvas/withRemoteSafeArea.js';import {useImageAttachments}from'../attachments/useImageAttachments.js';import {ComposerAttachmentBar}from'../attachments/ComposerAttachmentBar.js';import {NativeDictationBar}from'../audio-input/NativeDictationBar.js';import {AudioRecorderPanel}from'../audio-input/AudioRecorderPanel.js';import {MicErrorBoundary}from'../audio-input/MicErrorBoundary.js';import {isNativeDictationAvailable}from'../audio-input/nativeDictation.js';import {requestMicPermission}from'../audio-input/useAudioPermission.js';import {ChatTranscript}from'../chat/ChatTranscript.js';import ThinkingIndicator from'../../components/ThinkingIndicator.js';var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
17
+ function NativeAgentChat({
18
+ title,
19
+ visible,
20
+ onClose,
21
+ messages,
22
+ onSend,
23
+ onClear,
24
+ busy = false,
25
+ streamingContent = null,
26
+ error = null,
27
+ placeholder = "Ask anything\u2026",
28
+ emptyTitle,
29
+ emptyBody,
30
+ suggestions = [],
31
+ beforeComposer,
32
+ composerAccessory,
33
+ paneOverlay,
34
+ headerTrailing,
35
+ belowHeader,
36
+ composerLead,
37
+ draft: draftProp,
38
+ onDraftChange,
39
+ composerSeed,
40
+ composerSeedKey,
41
+ onComposerSeedConsumed,
42
+ embedded = false,
43
+ onSwipeLeft,
44
+ enableVoice = true,
45
+ enableAttachments = true,
46
+ isDark = false,
47
+ ink = "#0f172a",
48
+ muted = "#64748b",
49
+ screen = "#f8fafc",
50
+ border = "#e8ecf1"
51
+ }) {
52
+ const insets = useSafeInsets();
53
+ const draftControlled = onDraftChange !== void 0;
54
+ const [internalDraft, setInternalDraft] = useState("");
55
+ const draft = draftControlled ? draftProp != null ? draftProp : "" : internalDraft;
56
+ const draftRef = useRef(draft);
57
+ draftRef.current = draft;
58
+ const setDraft = (next) => {
59
+ const value = typeof next === "function" ? next(draftRef.current) : next;
60
+ if (draftControlled) onDraftChange == null ? void 0 : onDraftChange(value);
61
+ else setInternalDraft(value);
62
+ };
63
+ useEffect(() => {
64
+ if (composerSeed == null) return;
65
+ setDraft((prev) => prev.trim() ? `${composerSeed}
66
+
67
+ ${prev}` : composerSeed);
68
+ onComposerSeedConsumed == null ? void 0 : onComposerSeedConsumed();
69
+ }, [composerSeed, composerSeedKey]);
70
+ const attachments = useImageAttachments();
71
+ const [showNativeDictation, setShowNativeDictation] = useState(false);
72
+ const [showAudioRecorder, setShowAudioRecorder] = useState(false);
73
+ const [voiceError, setVoiceError] = useState(null);
74
+ const canSend = draft.trim().length > 0 || attachments.pending.length > 0;
75
+ const listening = showNativeDictation || showAudioRecorder;
76
+ const submit = (text = draft, files) => {
77
+ const trimmed = text.trim();
78
+ const pending = attachments.forSend();
79
+ if (!trimmed && !(pending == null ? void 0 : pending.length)) return;
80
+ setDraft("");
81
+ attachments.clear();
82
+ onSend(trimmed, pending);
83
+ };
84
+ const openWhisperRecorder = useCallback(() => {
85
+ setVoiceError(null);
86
+ void (async () => {
87
+ const {
88
+ granted,
89
+ error: error2
90
+ } = await requestMicPermission();
91
+ if (!granted) {
92
+ setVoiceError(error2 || "Microphone is not available.");
93
+ return;
94
+ }
95
+ setShowAudioRecorder(true);
96
+ })();
97
+ }, []);
98
+ const handleMicPress = useCallback(() => {
99
+ if (listening) {
100
+ setShowNativeDictation(false);
101
+ setShowAudioRecorder(false);
102
+ return;
103
+ }
104
+ setVoiceError(null);
105
+ Keyboard.dismiss();
106
+ if (isNativeDictationAvailable()) {
107
+ setShowNativeDictation(true);
108
+ return;
109
+ }
110
+ openWhisperRecorder();
111
+ }, [listening, openWhisperRecorder]);
112
+ const pasteTranscript = useCallback((text) => {
113
+ const cleaned = (text != null ? text : "").trim();
114
+ if (!cleaned) return;
115
+ setDraft((prev) => prev.trim() ? `${prev.trim()} ${cleaned}` : cleaned);
116
+ }, []);
117
+ const openPicker = useCallback((fn) => {
118
+ Keyboard.dismiss();
119
+ InteractionManager.runAfterInteractions(() => {
120
+ setTimeout(() => {
121
+ void fn();
122
+ }, 350);
123
+ });
124
+ }, []);
125
+ const banner = voiceError || attachments.error || error;
126
+ const swipeAway = useMemo(() => {
127
+ if (!onSwipeLeft) return null;
128
+ return PanResponder.create({
129
+ onMoveShouldSetPanResponder: (_e, g) => g.dx > 10 && Math.abs(g.dx) > Math.abs(g.dy),
130
+ onPanResponderRelease: (_e, g) => {
131
+ if (g.dx >= 48 && Math.abs(g.dx) > Math.abs(g.dy) * 1.15) onSwipeLeft();
132
+ }
133
+ });
134
+ }, [onSwipeLeft]);
135
+ if (!visible) return null;
136
+ return /* @__PURE__ */ jsxs(View, { style: [StyleSheet.absoluteFill, styles.overlay, {
137
+ backgroundColor: screen
138
+ }], pointerEvents: "auto", children: [
139
+ swipeAway ? /* @__PURE__ */ jsx(View, __spreadValues({ style: styles.dismissSwipeEdge }, swipeAway.panHandlers)) : null,
140
+ /* @__PURE__ */ jsxs(KeyboardAvoidingView, { style: [styles.fill, {
141
+ backgroundColor: screen,
142
+ paddingTop: embedded ? 8 : Math.max(insets.top, 8)
143
+ }], behavior: Platform.OS === "ios" ? "padding" : void 0, children: [
144
+ /* @__PURE__ */ jsxs(View, { style: [styles.head, {
145
+ borderColor: border
146
+ }], children: [
147
+ /* @__PURE__ */ jsxs(View, { style: styles.headTitle, children: [
148
+ /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "creation", size: 16, color: ink }),
149
+ /* @__PURE__ */ jsx(Text, { style: [styles.title, {
150
+ color: ink
151
+ }], children: title })
152
+ ] }),
153
+ /* @__PURE__ */ jsxs(View, { style: styles.headActions, children: [
154
+ onClear && messages.length > 0 ? /* @__PURE__ */ jsx(Pressable, { onPress: onClear, hitSlop: 10, accessibilityRole: "button", accessibilityLabel: "Clear chat", children: /* @__PURE__ */ jsx(Feather, { name: "trash-2", size: 18, color: muted }) }) : null,
155
+ headerTrailing,
156
+ /* @__PURE__ */ jsx(Pressable, { onPress: onClose, hitSlop: 10, accessibilityLabel: `Close ${title}`, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "close", size: 22, color: muted }) })
157
+ ] })
158
+ ] }),
159
+ belowHeader,
160
+ messages.length === 0 && !streamingContent ? /* @__PURE__ */ jsx(ScrollView, { style: styles.fill, contentContainerStyle: styles.emptyScroll, keyboardShouldPersistTaps: "handled", keyboardDismissMode: Platform.OS === "ios" ? "interactive" : "on-drag", showsVerticalScrollIndicator: false, children: /* @__PURE__ */ jsxs(Pressable, { style: styles.empty, onPress: dismissKeyboard, accessible: false, children: [
161
+ emptyTitle ? /* @__PURE__ */ jsx(Text, { style: [styles.emptyTitle, {
162
+ color: ink
163
+ }], children: emptyTitle }) : null,
164
+ emptyBody ? /* @__PURE__ */ jsx(Text, { style: [styles.emptyBody, {
165
+ color: muted
166
+ }], children: emptyBody }) : null,
167
+ suggestions.length > 0 ? /* @__PURE__ */ jsx(View, { style: styles.chips, children: suggestions.map((chip) => /* @__PURE__ */ jsx(Pressable, { onPress: () => {
168
+ var _a;
169
+ dismissKeyboard();
170
+ submit((_a = chip.prompt) != null ? _a : chip.label);
171
+ }, style: [styles.chip, {
172
+ borderColor: border,
173
+ backgroundColor: isDark ? "#1e293b" : "#fff"
174
+ }], children: /* @__PURE__ */ jsx(Text, { style: [styles.chipText, {
175
+ color: ink
176
+ }], children: chip.label }) }, chip.id)) }) : null
177
+ ] }) }) : /* @__PURE__ */ jsxs(Pressable, { style: styles.fill, onPress: dismissKeyboard, accessible: false, children: [
178
+ /* @__PURE__ */ jsx(ChatTranscript, { messages, streamingContent: streamingContent != null ? streamingContent : void 0, isDark, listFooter: beforeComposer }),
179
+ busy && !(streamingContent == null ? void 0 : streamingContent.trim()) ? /* @__PURE__ */ jsx(View, { style: styles.thinking, children: /* @__PURE__ */ jsx(ThinkingIndicator, { color: muted }) }) : null
180
+ ] }),
181
+ /* @__PURE__ */ jsxs(View, { style: [styles.composerWrap, {
182
+ borderColor: border,
183
+ paddingBottom: Math.max(insets.bottom, 10)
184
+ }], children: [
185
+ composerLead,
186
+ banner ? /* @__PURE__ */ jsx(View, { style: [styles.errorBanner, {
187
+ backgroundColor: isDark ? "#2b1a1d" : "#fef2f2"
188
+ }], children: /* @__PURE__ */ jsx(Text, { style: styles.errorText, children: banner }) }) : null,
189
+ showNativeDictation ? /* @__PURE__ */ jsx(MicErrorBoundary, { onCancel: () => setShowNativeDictation(false), onError: () => {
190
+ setShowNativeDictation(false);
191
+ openWhisperRecorder();
192
+ }, children: /* @__PURE__ */ jsx(NativeDictationBar, { isDark, onInterim: () => void 0, onTranscriptionComplete: (text) => {
193
+ setShowNativeDictation(false);
194
+ pasteTranscript(text);
195
+ }, onCancel: () => setShowNativeDictation(false), onFallback: () => {
196
+ setShowNativeDictation(false);
197
+ openWhisperRecorder();
198
+ } }) }) : showAudioRecorder ? /* @__PURE__ */ jsx(MicErrorBoundary, { onCancel: () => setShowAudioRecorder(false), onError: (err) => {
199
+ setShowAudioRecorder(false);
200
+ setVoiceError(err);
201
+ }, children: /* @__PURE__ */ jsx(AudioRecorderPanel, { isDark, onTranscriptionComplete: (text) => {
202
+ setShowAudioRecorder(false);
203
+ pasteTranscript(text);
204
+ }, onCancel: () => setShowAudioRecorder(false), onError: (err) => {
205
+ setShowAudioRecorder(false);
206
+ setVoiceError(err);
207
+ } }) }) : /* @__PURE__ */ jsxs(View, { style: [styles.composerCard, {
208
+ borderColor: border,
209
+ backgroundColor: isDark ? "#111827" : "#fff"
210
+ }], children: [
211
+ enableAttachments ? /* @__PURE__ */ jsx(ComposerAttachmentBar, { attachments: attachments.pending, onRemove: attachments.remove, isDark }) : null,
212
+ /* @__PURE__ */ jsxs(View, { style: styles.inputRow, children: [
213
+ /* @__PURE__ */ jsx(TextInput, { value: draft, onChangeText: (next) => {
214
+ setDraft(next);
215
+ if (voiceError) setVoiceError(null);
216
+ }, placeholder: listening ? "Listening\u2026 speak your request" : placeholder, placeholderTextColor: muted, multiline: true, textAlignVertical: "top", onSubmitEditing: () => submit(), style: [styles.input, {
217
+ color: ink
218
+ }], accessibilityLabel: placeholder }),
219
+ enableVoice ? /* @__PURE__ */ jsx(Pressable, { onPress: handleMicPress, style: [styles.mic, listening && styles.micLive], accessibilityRole: "button", accessibilityLabel: listening ? "Stop listening" : "Start voice input", children: /* @__PURE__ */ jsx(Feather, { name: listening ? "square" : "mic", size: 16, color: listening ? "#b91c1c" : muted }) }) : null,
220
+ canSend ? /* @__PURE__ */ jsx(Pressable, { onPress: () => submit(), style: [styles.send, busy && {
221
+ opacity: 0.85
222
+ }], accessibilityRole: "button", accessibilityLabel: "Send", children: /* @__PURE__ */ jsx(Feather, { name: "send", size: 14, color: "#fff", style: styles.sendIcon }) }) : null
223
+ ] }),
224
+ enableAttachments || composerAccessory ? /* @__PURE__ */ jsxs(View, { style: styles.tools, children: [
225
+ enableAttachments ? /* @__PURE__ */ jsxs(Fragment, { children: [
226
+ /* @__PURE__ */ jsx(Pressable, { onPress: () => openPicker(attachments.pickFromLibrary), onLongPress: () => openPicker(attachments.captureFromCamera), disabled: attachments.busy, style: styles.toolBtn, accessibilityRole: "button", accessibilityLabel: "Add image or screenshot", children: attachments.busyKind === "library" || attachments.busyKind === "camera" ? /* @__PURE__ */ jsx(ActivityIndicator, { size: "small" }) : /* @__PURE__ */ jsx(Feather, { name: "image", size: 18, color: muted }) }),
227
+ /* @__PURE__ */ jsx(Pressable, { onPress: () => openPicker(attachments.pickDocuments), disabled: attachments.busy, style: styles.toolBtn, accessibilityRole: "button", accessibilityLabel: "Attach files", children: attachments.busyKind === "documents" ? /* @__PURE__ */ jsx(ActivityIndicator, { size: "small" }) : /* @__PURE__ */ jsx(Feather, { name: "paperclip", size: 18, color: muted }) })
228
+ ] }) : null,
229
+ composerAccessory ? /* @__PURE__ */ jsx(View, { style: styles.toolsAccessory, children: composerAccessory }) : null
230
+ ] }) : null
231
+ ] })
232
+ ] })
233
+ ] }),
234
+ paneOverlay
235
+ ] });
236
+ }
237
+ const styles = StyleSheet.create({
238
+ overlay: {
239
+ zIndex: 200,
240
+ elevation: 200
241
+ },
242
+ dismissSwipeEdge: {
243
+ position: "absolute",
244
+ top: 0,
245
+ left: 0,
246
+ bottom: 0,
247
+ width: 40,
248
+ zIndex: 220
249
+ },
250
+ fill: {
251
+ flex: 1,
252
+ overflow: "hidden"
253
+ },
254
+ head: {
255
+ flexDirection: "row",
256
+ alignItems: "center",
257
+ justifyContent: "space-between",
258
+ paddingHorizontal: 16,
259
+ paddingBottom: 10,
260
+ borderBottomWidth: StyleSheet.hairlineWidth
261
+ },
262
+ headTitle: {
263
+ flexDirection: "row",
264
+ alignItems: "center",
265
+ gap: 8
266
+ },
267
+ headActions: {
268
+ flexDirection: "row",
269
+ alignItems: "center",
270
+ gap: 12
271
+ },
272
+ title: {
273
+ fontSize: 16,
274
+ fontWeight: "700"
275
+ },
276
+ emptyScroll: {
277
+ flexGrow: 1
278
+ },
279
+ empty: {
280
+ flexGrow: 1,
281
+ gap: 10,
282
+ paddingTop: 20,
283
+ paddingHorizontal: 16
284
+ },
285
+ thinking: {
286
+ paddingHorizontal: 16,
287
+ paddingBottom: 8
288
+ },
289
+ emptyTitle: {
290
+ fontSize: 18,
291
+ fontWeight: "700",
292
+ letterSpacing: -0.3
293
+ },
294
+ emptyBody: {
295
+ fontSize: 14,
296
+ lineHeight: 20
297
+ },
298
+ chips: {
299
+ flexDirection: "row",
300
+ flexWrap: "wrap",
301
+ gap: 8,
302
+ marginTop: 4
303
+ },
304
+ chip: {
305
+ borderWidth: 1,
306
+ borderRadius: 999,
307
+ paddingHorizontal: 12,
308
+ paddingVertical: 8
309
+ },
310
+ chipText: {
311
+ fontSize: 13,
312
+ fontWeight: "600"
313
+ },
314
+ composerWrap: {
315
+ paddingHorizontal: 12,
316
+ paddingTop: 8,
317
+ gap: 8
318
+ },
319
+ errorBanner: {
320
+ borderRadius: 10,
321
+ padding: 8
322
+ },
323
+ errorText: {
324
+ color: "#991b1b",
325
+ fontSize: 12
326
+ },
327
+ composerCard: {
328
+ borderWidth: StyleSheet.hairlineWidth,
329
+ borderRadius: 18,
330
+ paddingHorizontal: 12,
331
+ paddingTop: 10,
332
+ paddingBottom: 8,
333
+ gap: 4,
334
+ overflow: "visible"
335
+ },
336
+ inputRow: {
337
+ flexDirection: "row",
338
+ alignItems: "flex-end",
339
+ gap: 4,
340
+ minHeight: 44
341
+ },
342
+ input: {
343
+ flex: 1,
344
+ fontSize: 15,
345
+ maxHeight: 120,
346
+ minHeight: 40,
347
+ paddingVertical: 8,
348
+ paddingHorizontal: 2
349
+ },
350
+ tools: {
351
+ flexDirection: "row",
352
+ alignItems: "center",
353
+ gap: 2,
354
+ paddingTop: 2,
355
+ overflow: "visible"
356
+ },
357
+ toolsAccessory: {
358
+ marginLeft: "auto",
359
+ flexShrink: 1
360
+ },
361
+ mic: {
362
+ width: 32,
363
+ height: 32,
364
+ borderRadius: 8,
365
+ alignItems: "center",
366
+ justifyContent: "center",
367
+ marginBottom: 2
368
+ },
369
+ micLive: {
370
+ backgroundColor: "rgba(185,28,28,0.12)"
371
+ },
372
+ send: {
373
+ width: 32,
374
+ height: 32,
375
+ borderRadius: 16,
376
+ backgroundColor: "#ea580c",
377
+ alignItems: "center",
378
+ justifyContent: "center",
379
+ marginBottom: 2
380
+ },
381
+ sendIcon: {
382
+ transform: [{
383
+ rotate: "45deg"
384
+ }]
385
+ },
386
+ toolBtn: {
387
+ width: 36,
388
+ height: 36,
389
+ borderRadius: 8,
390
+ alignItems: "center",
391
+ justifyContent: "center"
392
+ }
393
+ });export{NativeAgentChat};//# sourceMappingURL=NativeAgentChat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeAgentChat.js","sources":["../../../src/features/agent-chat/NativeAgentChat.tsx"],"sourcesContent":["/**\n * Reusable native Agent panel (header + transcript + composer).\n * Composer matches web Shopping Agent: text + mic/send on the first row,\n * image + paperclip under the field. Surface cards (`beforeComposer`) scroll\n * with the thread as the list footer.\n */\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n ActivityIndicator,\n InteractionManager,\n Keyboard,\n KeyboardAvoidingView,\n PanResponder,\n Platform,\n Pressable,\n ScrollView,\n StyleSheet,\n Text,\n TextInput,\n View,\n} from 'react-native';\nimport { dismissKeyboard } from '../../utils/keyboardController';\nimport { Feather, MaterialCommunityIcons } from '@expo/vector-icons';\nimport { useSafeInsets } from '../canvas/withRemoteSafeArea';\nimport type { NativeAgentChatProps } from './types';\nimport type { MessageAttachment } from '../../hooks/useChatStream';\nimport { useImageAttachments } from '../attachments/useImageAttachments';\nimport { ComposerAttachmentBar } from '../attachments/ComposerAttachmentBar';\nimport { NativeDictationBar } from '../audio-input/NativeDictationBar';\nimport { AudioRecorderPanel } from '../audio-input/AudioRecorderPanel';\nimport { MicErrorBoundary } from '../audio-input/MicErrorBoundary';\nimport { isNativeDictationAvailable } from '../audio-input/nativeDictation';\nimport { requestMicPermission } from '../audio-input/useAudioPermission';\nimport { ChatTranscript } from '../chat/ChatTranscript';\nimport ThinkingIndicator from '../../components/ThinkingIndicator';\n\nexport function NativeAgentChat({\n title,\n visible,\n onClose,\n messages,\n onSend,\n onClear,\n busy = false,\n streamingContent = null,\n error = null,\n placeholder = 'Ask anything…',\n emptyTitle,\n emptyBody,\n suggestions = [],\n beforeComposer,\n composerAccessory,\n paneOverlay,\n headerTrailing,\n belowHeader,\n composerLead,\n draft: draftProp,\n onDraftChange,\n composerSeed,\n composerSeedKey,\n onComposerSeedConsumed,\n embedded = false,\n onSwipeLeft,\n enableVoice = true,\n enableAttachments = true,\n isDark = false,\n ink = '#0f172a',\n muted = '#64748b',\n screen = '#f8fafc',\n border = '#e8ecf1',\n}: NativeAgentChatProps) {\n const insets = useSafeInsets();\n const draftControlled = onDraftChange !== undefined;\n const [internalDraft, setInternalDraft] = useState('');\n const draft = draftControlled ? (draftProp ?? '') : internalDraft;\n const draftRef = useRef(draft);\n draftRef.current = draft;\n const setDraft = (next: string | ((prev: string) => string)) => {\n const value = typeof next === 'function' ? next(draftRef.current) : next;\n if (draftControlled) onDraftChange?.(value);\n else setInternalDraft(value);\n };\n useEffect(() => {\n if (composerSeed == null) return;\n setDraft((prev) => (prev.trim() ? `${composerSeed}\\n\\n${prev}` : composerSeed));\n onComposerSeedConsumed?.();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [composerSeed, composerSeedKey]);\n const attachments = useImageAttachments();\n const [showNativeDictation, setShowNativeDictation] = useState(false);\n const [showAudioRecorder, setShowAudioRecorder] = useState(false);\n const [voiceError, setVoiceError] = useState<string | null>(null);\n\n const canSend = draft.trim().length > 0 || attachments.pending.length > 0;\n const listening = showNativeDictation || showAudioRecorder;\n\n const submit = (text = draft, files?: MessageAttachment[]) => {\n const trimmed = text.trim();\n const pending = files ?? attachments.forSend();\n if (!trimmed && !pending?.length) return;\n setDraft('');\n attachments.clear();\n onSend(trimmed, pending);\n };\n\n const openWhisperRecorder = useCallback(() => {\n setVoiceError(null);\n void (async () => {\n const { granted, error } = await requestMicPermission();\n if (!granted) {\n setVoiceError(error || 'Microphone is not available.');\n return;\n }\n setShowAudioRecorder(true);\n })();\n }, []);\n\n const handleMicPress = useCallback(() => {\n if (listening) {\n setShowNativeDictation(false);\n setShowAudioRecorder(false);\n return;\n }\n setVoiceError(null);\n Keyboard.dismiss();\n if (isNativeDictationAvailable()) {\n setShowNativeDictation(true);\n return;\n }\n openWhisperRecorder();\n }, [listening, openWhisperRecorder]);\n\n const pasteTranscript = useCallback((text: string) => {\n const cleaned = (text ?? '').trim();\n if (!cleaned) return;\n setDraft((prev) => (prev.trim() ? `${prev.trim()} ${cleaned}` : cleaned));\n }, []);\n\n const openPicker = useCallback((fn: () => Promise<void>) => {\n Keyboard.dismiss();\n InteractionManager.runAfterInteractions(() => {\n setTimeout(() => {\n void fn();\n }, 350);\n });\n }, []);\n\n const banner = voiceError || attachments.error || error;\n\n const swipeAway = useMemo(() => {\n if (!onSwipeLeft) return null;\n return PanResponder.create({\n onMoveShouldSetPanResponder: (_e, g) => g.dx > 10 && Math.abs(g.dx) > Math.abs(g.dy),\n onPanResponderRelease: (_e, g) => {\n if (g.dx >= 48 && Math.abs(g.dx) > Math.abs(g.dy) * 1.15) onSwipeLeft();\n },\n });\n }, [onSwipeLeft]);\n\n if (!visible) return null;\n\n return (\n <View style={[StyleSheet.absoluteFill, styles.overlay, { backgroundColor: screen }]} pointerEvents=\"auto\">\n {swipeAway ? <View style={styles.dismissSwipeEdge} {...swipeAway.panHandlers} /> : null}\n <KeyboardAvoidingView\n style={[styles.fill, { backgroundColor: screen, paddingTop: embedded ? 8 : Math.max(insets.top, 8) }]}\n behavior={Platform.OS === 'ios' ? 'padding' : undefined}\n >\n <View style={[styles.head, { borderColor: border }]}>\n <View style={styles.headTitle}>\n <MaterialCommunityIcons name=\"creation\" size={16} color={ink} />\n <Text style={[styles.title, { color: ink }]}>{title}</Text>\n </View>\n <View style={styles.headActions}>\n {onClear && messages.length > 0 ? (\n <Pressable\n onPress={onClear}\n hitSlop={10}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Clear chat\"\n >\n <Feather name=\"trash-2\" size={18} color={muted} />\n </Pressable>\n ) : null}\n {headerTrailing}\n <Pressable onPress={onClose} hitSlop={10} accessibilityLabel={`Close ${title}`}>\n <MaterialCommunityIcons name=\"close\" size={22} color={muted} />\n </Pressable>\n </View>\n </View>\n {belowHeader}\n\n {messages.length === 0 && !streamingContent ? (\n <ScrollView\n style={styles.fill}\n contentContainerStyle={styles.emptyScroll}\n keyboardShouldPersistTaps=\"handled\"\n keyboardDismissMode={Platform.OS === 'ios' ? 'interactive' : 'on-drag'}\n showsVerticalScrollIndicator={false}\n >\n <Pressable style={styles.empty} onPress={dismissKeyboard} accessible={false}>\n {emptyTitle ? <Text style={[styles.emptyTitle, { color: ink }]}>{emptyTitle}</Text> : null}\n {emptyBody ? <Text style={[styles.emptyBody, { color: muted }]}>{emptyBody}</Text> : null}\n {suggestions.length > 0 ? (\n <View style={styles.chips}>\n {suggestions.map((chip) => (\n <Pressable\n key={chip.id}\n onPress={() => {\n dismissKeyboard();\n submit(chip.prompt ?? chip.label);\n }}\n style={[\n styles.chip,\n {\n borderColor: border,\n backgroundColor: isDark ? '#1e293b' : '#fff',\n },\n ]}\n >\n <Text style={[styles.chipText, { color: ink }]}>{chip.label}</Text>\n </Pressable>\n ))}\n </View>\n ) : null}\n </Pressable>\n </ScrollView>\n ) : (\n <Pressable style={styles.fill} onPress={dismissKeyboard} accessible={false}>\n <ChatTranscript\n messages={messages}\n streamingContent={streamingContent ?? undefined}\n isDark={isDark}\n listFooter={beforeComposer}\n />\n {busy && !streamingContent?.trim() ? (\n <View style={styles.thinking}>\n <ThinkingIndicator color={muted} />\n </View>\n ) : null}\n </Pressable>\n )}\n\n <View\n style={[styles.composerWrap, { borderColor: border, paddingBottom: Math.max(insets.bottom, 10) }]}\n >\n {composerLead}\n {banner ? (\n <View style={[styles.errorBanner, { backgroundColor: isDark ? '#2b1a1d' : '#fef2f2' }]}>\n <Text style={styles.errorText}>{banner}</Text>\n </View>\n ) : null}\n\n {showNativeDictation ? (\n <MicErrorBoundary\n onCancel={() => setShowNativeDictation(false)}\n onError={() => {\n setShowNativeDictation(false);\n openWhisperRecorder();\n }}\n >\n <NativeDictationBar\n isDark={isDark}\n onInterim={() => undefined}\n onTranscriptionComplete={(text) => {\n setShowNativeDictation(false);\n pasteTranscript(text);\n }}\n onCancel={() => setShowNativeDictation(false)}\n onFallback={() => {\n setShowNativeDictation(false);\n openWhisperRecorder();\n }}\n />\n </MicErrorBoundary>\n ) : showAudioRecorder ? (\n <MicErrorBoundary\n onCancel={() => setShowAudioRecorder(false)}\n onError={(err) => {\n setShowAudioRecorder(false);\n setVoiceError(err);\n }}\n >\n <AudioRecorderPanel\n isDark={isDark}\n onTranscriptionComplete={(text) => {\n setShowAudioRecorder(false);\n pasteTranscript(text);\n }}\n onCancel={() => setShowAudioRecorder(false)}\n onError={(err) => {\n setShowAudioRecorder(false);\n setVoiceError(err);\n }}\n />\n </MicErrorBoundary>\n ) : (\n <View\n style={[\n styles.composerCard,\n { borderColor: border, backgroundColor: isDark ? '#111827' : '#fff' },\n ]}\n >\n {enableAttachments ? (\n <ComposerAttachmentBar\n attachments={attachments.pending}\n onRemove={attachments.remove}\n isDark={isDark}\n />\n ) : null}\n <View style={styles.inputRow}>\n <TextInput\n value={draft}\n onChangeText={(next) => {\n setDraft(next);\n if (voiceError) setVoiceError(null);\n }}\n placeholder={listening ? 'Listening… speak your request' : placeholder}\n placeholderTextColor={muted}\n multiline\n textAlignVertical=\"top\"\n onSubmitEditing={() => submit()}\n style={[styles.input, { color: ink }]}\n accessibilityLabel={placeholder}\n />\n {enableVoice ? (\n <Pressable\n onPress={handleMicPress}\n style={[styles.mic, listening && styles.micLive]}\n accessibilityRole=\"button\"\n accessibilityLabel={listening ? 'Stop listening' : 'Start voice input'}\n >\n <Feather\n name={listening ? 'square' : 'mic'}\n size={16}\n color={listening ? '#b91c1c' : muted}\n />\n </Pressable>\n ) : null}\n {canSend ? (\n <Pressable\n onPress={() => submit()}\n style={[styles.send, busy && { opacity: 0.85 }]}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Send\"\n >\n <Feather name=\"send\" size={14} color=\"#fff\" style={styles.sendIcon} />\n </Pressable>\n ) : null}\n </View>\n {enableAttachments || composerAccessory ? (\n <View style={styles.tools}>\n {enableAttachments ? (\n <>\n <Pressable\n onPress={() => openPicker(attachments.pickFromLibrary)}\n onLongPress={() => openPicker(attachments.captureFromCamera)}\n disabled={attachments.busy}\n style={styles.toolBtn}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Add image or screenshot\"\n >\n {attachments.busyKind === 'library' ||\n attachments.busyKind === 'camera' ? (\n <ActivityIndicator size=\"small\" />\n ) : (\n <Feather name=\"image\" size={18} color={muted} />\n )}\n </Pressable>\n <Pressable\n onPress={() => openPicker(attachments.pickDocuments)}\n disabled={attachments.busy}\n style={styles.toolBtn}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Attach files\"\n >\n {attachments.busyKind === 'documents' ? (\n <ActivityIndicator size=\"small\" />\n ) : (\n <Feather name=\"paperclip\" size={18} color={muted} />\n )}\n </Pressable>\n </>\n ) : null}\n {composerAccessory ? (\n <View style={styles.toolsAccessory}>{composerAccessory}</View>\n ) : null}\n </View>\n ) : null}\n </View>\n )}\n </View>\n </KeyboardAvoidingView>\n {paneOverlay}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n overlay: { zIndex: 200, elevation: 200 },\n dismissSwipeEdge: {\n position: 'absolute',\n top: 0,\n left: 0,\n bottom: 0,\n width: 40,\n zIndex: 220,\n },\n fill: { flex: 1, overflow: 'hidden' },\n head: {\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingHorizontal: 16,\n paddingBottom: 10,\n borderBottomWidth: StyleSheet.hairlineWidth,\n },\n headTitle: { flexDirection: 'row', alignItems: 'center', gap: 8 },\n headActions: { flexDirection: 'row', alignItems: 'center', gap: 12 },\n title: { fontSize: 16, fontWeight: '700' },\n emptyScroll: { flexGrow: 1 },\n empty: { flexGrow: 1, gap: 10, paddingTop: 20, paddingHorizontal: 16 },\n thinking: { paddingHorizontal: 16, paddingBottom: 8 },\n emptyTitle: { fontSize: 18, fontWeight: '700', letterSpacing: -0.3 },\n emptyBody: { fontSize: 14, lineHeight: 20 },\n chips: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, marginTop: 4 },\n chip: { borderWidth: 1, borderRadius: 999, paddingHorizontal: 12, paddingVertical: 8 },\n chipText: { fontSize: 13, fontWeight: '600' },\n composerWrap: { paddingHorizontal: 12, paddingTop: 8, gap: 8 },\n errorBanner: { borderRadius: 10, padding: 8 },\n errorText: { color: '#991b1b', fontSize: 12 },\n composerCard: {\n borderWidth: StyleSheet.hairlineWidth,\n borderRadius: 18,\n paddingHorizontal: 12,\n paddingTop: 10,\n paddingBottom: 8,\n gap: 4,\n overflow: 'visible',\n },\n inputRow: {\n flexDirection: 'row',\n alignItems: 'flex-end',\n gap: 4,\n minHeight: 44,\n },\n input: { flex: 1, fontSize: 15, maxHeight: 120, minHeight: 40, paddingVertical: 8, paddingHorizontal: 2 },\n tools: { flexDirection: 'row', alignItems: 'center', gap: 2, paddingTop: 2, overflow: 'visible' },\n toolsAccessory: { marginLeft: 'auto', flexShrink: 1 },\n mic: {\n width: 32,\n height: 32,\n borderRadius: 8,\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: 2,\n },\n micLive: { backgroundColor: 'rgba(185,28,28,0.12)' },\n send: {\n width: 32,\n height: 32,\n borderRadius: 16,\n backgroundColor: '#ea580c',\n alignItems: 'center',\n justifyContent: 'center',\n marginBottom: 2,\n },\n sendIcon: { transform: [{ rotate: '45deg' }] },\n toolBtn: {\n width: 36,\n height: 36,\n borderRadius: 8,\n alignItems: 'center',\n justifyContent: 'center',\n },\n});\n"],"names":["error"],"mappings":"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"}
@@ -96,6 +96,16 @@ function AppsCatalog({
96
96
  }));
97
97
  return;
98
98
  }
99
+ if (app.nativeRoute === "travel-native") {
100
+ navigation.dispatch(CommonActions.navigate({
101
+ name: "MainStack.TravelNative",
102
+ params: {
103
+ orgName: orgName != null ? orgName : void 0,
104
+ appTitle: "Travel"
105
+ }
106
+ }));
107
+ return;
108
+ }
99
109
  if (app.nativeRoute === "webbuilder") {
100
110
  const surfaceUrl = resolveSurfaceUrl(app, config);
101
111
  navigation.dispatch(CommonActions.navigate({
@@ -1 +1 @@
1
- {"version":3,"file":"AppsCatalog.js","sources":["../../../src/features/apps/AppsCatalog.tsx"],"sourcesContent":["/**\n * Full-screen Apps catalog: search + grouped tiles, then navigate into a\n * native surface or a new chat. Shared by the Apps screen (not a popup).\n */\nimport React, { useCallback, useMemo, useState } from 'react';\nimport { Pressable, ScrollView, StyleSheet, Text, TextInput, View, useColorScheme } from 'react-native';\nimport { CommonActions, useNavigation, useRoute } from '@react-navigation/native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { v4 as uuidv4 } from 'uuid';\nimport { config } from '../../config/env-config';\nimport { mobileTokens } from '../../theme/mobileTokens';\nimport { useChatMutations } from '../../hooks/useChatApi';\nimport { resolveSurfaceUrl } from './resolveSurfaceUrl';\nimport { groupMobileApps, MOBILE_APP_CATALOG, type MobileAppItem } from './mobileAppCatalog';\n\nfunction buildChannelTitle(channelId: string): string {\n return `chat-channel-${channelId}`;\n}\n\nexport function AppsCatalog({ orgName: orgNameProp }: { orgName?: string | null }) {\n const navigation = useNavigation<any>();\n const route = useRoute<any>();\n const colorScheme = useColorScheme();\n const isDark = colorScheme === 'dark';\n const { createChannel } = useChatMutations();\n const [query, setQuery] = useState('');\n\n const orgName = useMemo(() => {\n if (typeof orgNameProp === 'string' && orgNameProp.trim()) return orgNameProp.trim();\n const raw = (route?.params?.orgName as string | undefined) ?? '';\n return typeof raw === 'string' && raw.trim() ? raw.trim() : null;\n }, [orgNameProp, route?.params?.orgName]);\n\n const grouped = useMemo(() => groupMobileApps(MOBILE_APP_CATALOG, query), [query]);\n\n const muted = isDark ? '#94a3b8' : mobileTokens.color.textMuted;\n const foreground = isDark ? '#e2e8f0' : mobileTokens.color.text;\n const surface = isDark ? '#111827' : mobileTokens.color.surface;\n const screenBg = isDark ? '#0f172a' : mobileTokens.color.bg;\n const borderColor = isDark ? 'rgba(148,163,184,0.22)' : mobileTokens.color.border;\n const fieldBg = isDark ? '#1e293b' : mobileTokens.color.surfaceMuted;\n const accent = isDark ? '#a5b4fc' : mobileTokens.color.primary;\n const accentSoft = isDark ? 'rgba(99,102,241,0.18)' : mobileTokens.color.primarySoft;\n\n const openApp = useCallback(\n (app: MobileAppItem) => {\n const channelId = uuidv4();\n const params: Record<string, unknown> = {\n orgName: orgName ?? undefined,\n channelId,\n appTitle: app.label,\n };\n\n if (app.nativeRoute === 'characters-native') {\n // Same wiring as AppsMenu: the tile opens the self-contained native\n // character studio (never a chat with the tile's prompt). The host\n // contributes only the session token + subgraph endpoint, built in\n // the screen, so no manifest/handoff params are needed here.\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.CharactersNative',\n params,\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'canvas-native') {\n // Web canvas opens the boards grid first. Do not mint a chat\n // channelId here — that id is not an index row, and passing it\n // looks like a deep link into a board that does not exist.\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.CanvasNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Canvas' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'chat-native') {\n // Opens the conversation list. Deliberately no channelId: the\n // uuid minted above is an AI-chat channel, not a messenger\n // channel, and passing it would read as a deep link into a\n // thread that does not exist.\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.ChatNative',\n params: { orgName: orgName ?? undefined },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'billing-native') {\n navigation.navigate('MainStack.Billing', { orgName: orgName ?? undefined });\n return;\n }\n\n if (app.nativeRoute === 'shopping-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.ShoppingNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Shop' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'webbuilder') {\n const surfaceUrl = resolveSurfaceUrl(app, config);\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.WebBuilder',\n params: surfaceUrl ? { ...params, url: surfaceUrl } : params,\n }),\n );\n return;\n }\n\n void createChannel({\n id: channelId,\n title: buildChannelTitle(channelId),\n isShared: false,\n sharedSlug: null,\n isArchived: false,\n isPinned: false,\n model: null,\n systemPrompt: null,\n orgName,\n } as any).catch((err) => {\n console.error('[AppsCatalog] createChannel failed:', err);\n });\n\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.Chat',\n params: {\n ...params,\n initialQuery: app.prompt,\n initialMode: 'chat',\n },\n }),\n );\n },\n [createChannel, navigation, orgName],\n );\n\n return (\n <View style={[styles.root, { backgroundColor: screenBg }]}>\n <View style={[styles.searchWrap, { backgroundColor: fieldBg, borderColor }]}>\n <MaterialCommunityIcons name=\"magnify\" size={18} color={muted} />\n <TextInput\n value={query}\n onChangeText={setQuery}\n placeholder=\"Search apps\"\n placeholderTextColor={muted}\n autoCorrect={false}\n autoCapitalize=\"none\"\n style={[styles.searchInput, { color: foreground }]}\n />\n </View>\n <ScrollView keyboardShouldPersistTaps=\"handled\" contentContainerStyle={styles.list}>\n {grouped.length === 0 ? (\n <Text style={[styles.empty, { color: muted }]}>No apps match that search.</Text>\n ) : (\n grouped.map((group) => (\n <View key={group.label} style={styles.group}>\n <Text style={[styles.groupLabel, { color: muted }]}>{group.label}</Text>\n <View style={styles.groupGrid}>\n {group.items.map((app) => (\n <Pressable\n key={app.key}\n onPress={() => openApp(app)}\n accessibilityRole=\"button\"\n accessibilityLabel={app.label}\n style={({ pressed }) => [\n styles.appTile,\n {\n backgroundColor: surface,\n borderColor,\n },\n pressed && { backgroundColor: accentSoft },\n ]}\n >\n <View style={[styles.appIcon, { backgroundColor: accentSoft }]}>\n <MaterialCommunityIcons name={app.icon} size={18} color={accent} />\n </View>\n <Text style={[styles.appLabel, { color: foreground }]} numberOfLines={2}>\n {app.label}\n </Text>\n </Pressable>\n ))}\n </View>\n </View>\n ))\n )}\n </ScrollView>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1,\n },\n searchWrap: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n marginHorizontal: 16,\n marginTop: 12,\n marginBottom: 8,\n borderWidth: 1,\n borderRadius: 12,\n paddingHorizontal: 12,\n minHeight: 42,\n },\n searchInput: {\n flex: 1,\n fontSize: 15,\n paddingVertical: 8,\n },\n list: {\n paddingHorizontal: 16,\n paddingTop: 8,\n paddingBottom: 28,\n gap: 16,\n },\n group: {\n gap: 8,\n },\n groupLabel: {\n fontSize: 11,\n fontWeight: '600',\n letterSpacing: 0.7,\n textTransform: 'uppercase',\n },\n groupGrid: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n gap: 8,\n },\n appTile: {\n width: '31%',\n flexGrow: 1,\n minWidth: 96,\n maxWidth: '32.5%',\n borderWidth: 1,\n borderRadius: 14,\n paddingHorizontal: 10,\n paddingVertical: 12,\n gap: 8,\n },\n appIcon: {\n width: 32,\n height: 32,\n borderRadius: 10,\n alignItems: 'center',\n justifyContent: 'center',\n },\n appLabel: {\n fontSize: 13,\n fontWeight: '600',\n lineHeight: 17,\n },\n empty: {\n textAlign: 'center',\n paddingVertical: 28,\n fontSize: 14,\n },\n});\n"],"names":["_a","uuidv4"],"mappings":";;;;;;;;;;;;;;;;;;;AAcA,SAAS,kBAAkB,SAA2B,EAAA;AACpD,EAAA,OAAO,gBAAgB,SAAS,CAAA,CAAA;AAClC;AACO,SAAS,WAAY,CAAA;AAAA,EAC1B,OAAS,EAAA;AACX,CAEG,EAAA;AArBH,EAAA,IAAA,EAAA;AAsBE,EAAA,MAAM,aAAa,aAAmB,EAAA;AACtC,EAAA,MAAM,QAAQ,QAAc,EAAA;AAC5B,EAAA,MAAM,cAAc,cAAe,EAAA;AACnC,EAAA,MAAM,SAAS,WAAgB,KAAA,MAAA;AAC/B,EAAM,MAAA;AAAA,IACJ;AAAA,MACE,gBAAiB,EAAA;AACrB,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,EAAE,CAAA;AACrC,EAAM,MAAA,OAAA,GAAU,QAAQ,MAAM;AA9BhC,IAAA,IAAAA,GAAA,EAAA,EAAA;AA+BI,IAAI,IAAA,OAAO,gBAAgB,QAAY,IAAA,WAAA,CAAY,MAAQ,EAAA,OAAO,YAAY,IAAK,EAAA;AACnF,IAAM,MAAA,GAAA,GAAA,CAAM,MAAAA,GAAA,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAO,WAAP,IAAAA,GAAAA,MAAAA,GAAAA,GAAAA,CAAe,YAAf,IAAgD,GAAA,EAAA,GAAA,EAAA;AAC5D,IAAO,OAAA,OAAO,QAAQ,QAAY,IAAA,GAAA,CAAI,MAAS,GAAA,GAAA,CAAI,MAAS,GAAA,IAAA;AAAA,KAC3D,CAAC,WAAA,EAAA,CAAa,oCAAO,MAAP,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAe,OAAO,CAAC,CAAA;AACxC,EAAM,MAAA,OAAA,GAAU,QAAQ,MAAM,eAAA,CAAgB,oBAAoB,KAAK,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AACjF,EAAA,MAAM,KAAQ,GAAA,MAAA,GAAS,SAAY,GAAA,YAAA,CAAa,KAAM,CAAA,SAAA;AACtD,EAAA,MAAM,UAAa,GAAA,MAAA,GAAS,SAAY,GAAA,YAAA,CAAa,KAAM,CAAA,IAAA;AAC3D,EAAA,MAAM,OAAU,GAAA,MAAA,GAAS,SAAY,GAAA,YAAA,CAAa,KAAM,CAAA,OAAA;AACxD,EAAA,MAAM,QAAW,GAAA,MAAA,GAAS,SAAY,GAAA,YAAA,CAAa,KAAM,CAAA,EAAA;AACzD,EAAA,MAAM,WAAc,GAAA,MAAA,GAAS,wBAA2B,GAAA,YAAA,CAAa,KAAM,CAAA,MAAA;AAC3E,EAAA,MAAM,OAAU,GAAA,MAAA,GAAS,SAAY,GAAA,YAAA,CAAa,KAAM,CAAA,YAAA;AACxD,EAAA,MAAM,MAAS,GAAA,MAAA,GAAS,SAAY,GAAA,YAAA,CAAa,KAAM,CAAA,OAAA;AACvD,EAAA,MAAM,UAAa,GAAA,MAAA,GAAS,uBAA0B,GAAA,YAAA,CAAa,KAAM,CAAA,WAAA;AACzE,EAAM,MAAA,OAAA,GAAU,WAAY,CAAA,CAAC,GAAuB,KAAA;AAClD,IAAA,MAAM,YAAYC,EAAO,EAAA;AACzB,IAAA,MAAM,MAAkC,GAAA;AAAA,MACtC,SAAS,OAAW,IAAA,IAAA,GAAA,OAAA,GAAA,MAAA;AAAA,MACpB,SAAA;AAAA,MACA,UAAU,GAAI,CAAA;AAAA,KAChB;AACA,IAAI,IAAA,GAAA,CAAI,gBAAgB,mBAAqB,EAAA;AAK3C,MAAW,UAAA,CAAA,QAAA,CAAS,cAAc,QAAS,CAAA;AAAA,QACzC,IAAM,EAAA,4BAAA;AAAA,QACN;AAAA,OACD,CAAC,CAAA;AACF,MAAA;AAAA;AAEF,IAAI,IAAA,GAAA,CAAI,gBAAgB,eAAiB,EAAA;AAIvC,MAAW,UAAA,CAAA,QAAA,CAAS,cAAc,QAAS,CAAA;AAAA,QACzC,IAAM,EAAA,wBAAA;AAAA,QACN,MAAQ,EAAA;AAAA,UACN,SAAS,OAAW,IAAA,IAAA,GAAA,OAAA,GAAA,MAAA;AAAA,UACpB,QAAU,EAAA;AAAA;AACZ,OACD,CAAC,CAAA;AACF,MAAA;AAAA;AAEF,IAAI,IAAA,GAAA,CAAI,gBAAgB,aAAe,EAAA;AAKrC,MAAW,UAAA,CAAA,QAAA,CAAS,cAAc,QAAS,CAAA;AAAA,QACzC,IAAM,EAAA,sBAAA;AAAA,QACN,MAAQ,EAAA;AAAA,UACN,SAAS,OAAW,IAAA,IAAA,GAAA,OAAA,GAAA;AAAA;AACtB,OACD,CAAC,CAAA;AACF,MAAA;AAAA;AAEF,IAAI,IAAA,GAAA,CAAI,gBAAgB,gBAAkB,EAAA;AACxC,MAAA,UAAA,CAAW,SAAS,mBAAqB,EAAA;AAAA,QACvC,SAAS,OAAW,IAAA,IAAA,GAAA,OAAA,GAAA;AAAA,OACrB,CAAA;AACD,MAAA;AAAA;AAEF,IAAI,IAAA,GAAA,CAAI,gBAAgB,iBAAmB,EAAA;AACzC,MAAW,UAAA,CAAA,QAAA,CAAS,cAAc,QAAS,CAAA;AAAA,QACzC,IAAM,EAAA,0BAAA;AAAA,QACN,MAAQ,EAAA;AAAA,UACN,SAAS,OAAW,IAAA,IAAA,GAAA,OAAA,GAAA,MAAA;AAAA,UACpB,QAAU,EAAA;AAAA;AACZ,OACD,CAAC,CAAA;AACF,MAAA;AAAA;AAEF,IAAI,IAAA,GAAA,CAAI,gBAAgB,YAAc,EAAA;AACpC,MAAM,MAAA,UAAA,GAAa,iBAAkB,CAAA,GAAA,EAAK,MAAM,CAAA;AAChD,MAAW,UAAA,CAAA,QAAA,CAAS,cAAc,QAAS,CAAA;AAAA,QACzC,IAAM,EAAA,sBAAA;AAAA,QACN,MAAA,EAAQ,UAAa,GAAA,aAAA,CAAA,cAAA,CAAA,EAAA,EAChB,MADgB,CAAA,EAAA;AAAA,UAEnB,GAAK,EAAA;AAAA,SACH,CAAA,GAAA;AAAA,OACL,CAAC,CAAA;AACF,MAAA;AAAA;AAEF,IAAA,KAAK,aAAc,CAAA;AAAA,MACjB,EAAI,EAAA,SAAA;AAAA,MACJ,KAAA,EAAO,kBAAkB,SAAS,CAAA;AAAA,MAClC,QAAU,EAAA,KAAA;AAAA,MACV,UAAY,EAAA,IAAA;AAAA,MACZ,UAAY,EAAA,KAAA;AAAA,MACZ,QAAU,EAAA,KAAA;AAAA,MACV,KAAO,EAAA,IAAA;AAAA,MACP,YAAc,EAAA,IAAA;AAAA,MACd;AAAA,KACM,CAAE,CAAA,KAAA,CAAM,CAAO,GAAA,KAAA;AACrB,MAAQ,OAAA,CAAA,KAAA,CAAM,uCAAuC,GAAG,CAAA;AAAA,KACzD,CAAA;AACD,IAAW,UAAA,CAAA,QAAA,CAAS,cAAc,QAAS,CAAA;AAAA,MACzC,IAAM,EAAA,gBAAA;AAAA,MACN,MAAA,EAAQ,iCACH,MADG,CAAA,EAAA;AAAA,QAEN,cAAc,GAAI,CAAA,MAAA;AAAA,QAClB,WAAa,EAAA;AAAA,OACf;AAAA,KACD,CAAC,CAAA;AAAA,GACD,EAAA,CAAC,aAAe,EAAA,UAAA,EAAY,OAAO,CAAC,CAAA;AACvC,EAAA,uBAAQ,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,IAAM,EAAA;AAAA,IAChC,eAAiB,EAAA;AAAA,GAClB,CACS,EAAA,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,UAAY,EAAA;AAAA,MACvC,eAAiB,EAAA,OAAA;AAAA,MACjB;AAAA,KACD,CACW,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,0BAAuB,IAAK,EAAA,SAAA,EAAU,IAAM,EAAA,EAAA,EAAI,OAAO,KAAO,EAAA,CAAA;AAAA,0BAC9D,SAAU,EAAA,EAAA,KAAA,EAAO,KAAO,EAAA,YAAA,EAAc,UAAU,WAAY,EAAA,aAAA,EAAc,oBAAsB,EAAA,KAAA,EAAO,aAAa,KAAO,EAAA,cAAA,EAAe,QAAO,KAAO,EAAA,CAAC,OAAO,WAAa,EAAA;AAAA,QACtL,KAAO,EAAA;AAAA,OACR,CAAG,EAAA;AAAA,KACE,EAAA,CAAA;AAAA,oBACC,GAAA,CAAA,UAAA,EAAA,EAAW,yBAA0B,EAAA,SAAA,EAAU,uBAAuB,MAAO,CAAA,IAAA,EACzE,QAAQ,EAAA,OAAA,CAAA,MAAA,KAAW,oBAAK,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,KAAO,EAAA;AAAA,MAC5D,KAAO,EAAA;AAAA,KACR,CAAG,EAAA,QAAA,EAAA,4BAAA,EAA0B,CAAU,GAAA,OAAA,CAAQ,GAAI,CAAA,CAAA,KAAA,qBAAU,IAAA,CAAA,IAAA,EAAA,EAAuB,KAAO,EAAA,MAAA,CAAO,KAC7E,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,UAAY,EAAA;AAAA,QACnD,KAAO,EAAA;AAAA,OACR,CAAI,EAAA,QAAA,EAAA,KAAA,CAAM,KAAM,EAAA,CAAA;AAAA,sBACG,GAAA,CAAC,QAAK,KAAO,EAAA,MAAA,CAAO,WACf,QAAM,EAAA,KAAA,CAAA,KAAA,CAAM,GAAI,CAAA,CAAA,GAAA,qBAAQ,IAAA,CAAA,SAAA,EAAA,EAAwB,SAAS,MAAM,OAAA,CAAQ,GAAG,CAAG,EAAA,iBAAA,EAAkB,UAAS,kBAAoB,EAAA,GAAA,CAAI,KAAO,EAAA,KAAA,EAAO,CAAC;AAAA,QACpK;AAAA,OACF,KAAM,CAAC,MAAA,CAAO,OAAS,EAAA;AAAA,QACrB,eAAiB,EAAA,OAAA;AAAA,QACjB;AAAA,SACC,OAAW,IAAA;AAAA,QACZ,eAAiB,EAAA;AAAA,OAClB,CAC6B,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,OAAS,EAAA;AAAA,UACxD,eAAiB,EAAA;AAAA,SAClB,CAC+B,EAAA,QAAA,kBAAA,GAAA,CAAC,sBAAuB,EAAA,EAAA,IAAA,EAAM,GAAI,CAAA,IAAA,EAAM,IAAM,EAAA,EAAA,EAAI,KAAO,EAAA,MAAA,EAAQ,CACrE,EAAA,CAAA;AAAA,wBACC,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,QAAU,EAAA;AAAA,UACzD,KAAO,EAAA;AAAA,SACR,CAAA,EAAG,aAAe,EAAA,CAAA,EACc,cAAI,KACT,EAAA;AAAA,OAjBgC,EAAA,EAAA,GAAA,CAAI,GAkBxC,CAAY,CACpB,EAAA;AAAA,KAxBkD,EAAA,EAAA,KAAA,CAAM,KAyB5D,CAAO,CACnB,EAAA;AAAA,GACJ,EAAA,CAAA;AACR;AACA,MAAM,MAAA,GAAS,WAAW,MAAO,CAAA;AAAA,EAC/B,IAAM,EAAA;AAAA,IACJ,IAAM,EAAA;AAAA,GACR;AAAA,EACA,UAAY,EAAA;AAAA,IACV,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA,QAAA;AAAA,IACZ,GAAK,EAAA,CAAA;AAAA,IACL,gBAAkB,EAAA,EAAA;AAAA,IAClB,SAAW,EAAA,EAAA;AAAA,IACX,YAAc,EAAA,CAAA;AAAA,IACd,WAAa,EAAA,CAAA;AAAA,IACb,YAAc,EAAA,EAAA;AAAA,IACd,iBAAmB,EAAA,EAAA;AAAA,IACnB,SAAW,EAAA;AAAA,GACb;AAAA,EACA,WAAa,EAAA;AAAA,IACX,IAAM,EAAA,CAAA;AAAA,IACN,QAAU,EAAA,EAAA;AAAA,IACV,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,IAAM,EAAA;AAAA,IACJ,iBAAmB,EAAA,EAAA;AAAA,IACnB,UAAY,EAAA,CAAA;AAAA,IACZ,aAAe,EAAA,EAAA;AAAA,IACf,GAAK,EAAA;AAAA,GACP;AAAA,EACA,KAAO,EAAA;AAAA,IACL,GAAK,EAAA;AAAA,GACP;AAAA,EACA,UAAY,EAAA;AAAA,IACV,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,KAAA;AAAA,IACZ,aAAe,EAAA,GAAA;AAAA,IACf,aAAe,EAAA;AAAA,GACjB;AAAA,EACA,SAAW,EAAA;AAAA,IACT,aAAe,EAAA,KAAA;AAAA,IACf,QAAU,EAAA,MAAA;AAAA,IACV,GAAK,EAAA;AAAA,GACP;AAAA,EACA,OAAS,EAAA;AAAA,IACP,KAAO,EAAA,KAAA;AAAA,IACP,QAAU,EAAA,CAAA;AAAA,IACV,QAAU,EAAA,EAAA;AAAA,IACV,QAAU,EAAA,OAAA;AAAA,IACV,WAAa,EAAA,CAAA;AAAA,IACb,YAAc,EAAA,EAAA;AAAA,IACd,iBAAmB,EAAA,EAAA;AAAA,IACnB,eAAiB,EAAA,EAAA;AAAA,IACjB,GAAK,EAAA;AAAA,GACP;AAAA,EACA,OAAS,EAAA;AAAA,IACP,KAAO,EAAA,EAAA;AAAA,IACP,MAAQ,EAAA,EAAA;AAAA,IACR,YAAc,EAAA,EAAA;AAAA,IACd,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA;AAAA,GAClB;AAAA,EACA,QAAU,EAAA;AAAA,IACR,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,KAAA;AAAA,IACZ,UAAY,EAAA;AAAA,GACd;AAAA,EACA,KAAO,EAAA;AAAA,IACL,SAAW,EAAA,QAAA;AAAA,IACX,eAAiB,EAAA,EAAA;AAAA,IACjB,QAAU,EAAA;AAAA;AAEd,CAAC,CAAA"}
1
+ {"version":3,"file":"AppsCatalog.js","sources":["../../../src/features/apps/AppsCatalog.tsx"],"sourcesContent":["/**\n * Full-screen Apps catalog: search + grouped tiles, then navigate into a\n * native surface or a new chat. Shared by the Apps screen (not a popup).\n */\nimport React, { useCallback, useMemo, useState } from 'react';\nimport { Pressable, ScrollView, StyleSheet, Text, TextInput, View, useColorScheme } from 'react-native';\nimport { CommonActions, useNavigation, useRoute } from '@react-navigation/native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { v4 as uuidv4 } from 'uuid';\nimport { config } from '../../config/env-config';\nimport { mobileTokens } from '../../theme/mobileTokens';\nimport { useChatMutations } from '../../hooks/useChatApi';\nimport { resolveSurfaceUrl } from './resolveSurfaceUrl';\nimport { groupMobileApps, MOBILE_APP_CATALOG, type MobileAppItem } from './mobileAppCatalog';\n\nfunction buildChannelTitle(channelId: string): string {\n return `chat-channel-${channelId}`;\n}\n\nexport function AppsCatalog({ orgName: orgNameProp }: { orgName?: string | null }) {\n const navigation = useNavigation<any>();\n const route = useRoute<any>();\n const colorScheme = useColorScheme();\n const isDark = colorScheme === 'dark';\n const { createChannel } = useChatMutations();\n const [query, setQuery] = useState('');\n\n const orgName = useMemo(() => {\n if (typeof orgNameProp === 'string' && orgNameProp.trim()) return orgNameProp.trim();\n const raw = (route?.params?.orgName as string | undefined) ?? '';\n return typeof raw === 'string' && raw.trim() ? raw.trim() : null;\n }, [orgNameProp, route?.params?.orgName]);\n\n const grouped = useMemo(() => groupMobileApps(MOBILE_APP_CATALOG, query), [query]);\n\n const muted = isDark ? '#94a3b8' : mobileTokens.color.textMuted;\n const foreground = isDark ? '#e2e8f0' : mobileTokens.color.text;\n const surface = isDark ? '#111827' : mobileTokens.color.surface;\n const screenBg = isDark ? '#0f172a' : mobileTokens.color.bg;\n const borderColor = isDark ? 'rgba(148,163,184,0.22)' : mobileTokens.color.border;\n const fieldBg = isDark ? '#1e293b' : mobileTokens.color.surfaceMuted;\n const accent = isDark ? '#a5b4fc' : mobileTokens.color.primary;\n const accentSoft = isDark ? 'rgba(99,102,241,0.18)' : mobileTokens.color.primarySoft;\n\n const openApp = useCallback(\n (app: MobileAppItem) => {\n const channelId = uuidv4();\n const params: Record<string, unknown> = {\n orgName: orgName ?? undefined,\n channelId,\n appTitle: app.label,\n };\n\n if (app.nativeRoute === 'characters-native') {\n // Same wiring as AppsMenu: the tile opens the self-contained native\n // character studio (never a chat with the tile's prompt). The host\n // contributes only the session token + subgraph endpoint, built in\n // the screen, so no manifest/handoff params are needed here.\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.CharactersNative',\n params,\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'canvas-native') {\n // Web canvas opens the boards grid first. Do not mint a chat\n // channelId here — that id is not an index row, and passing it\n // looks like a deep link into a board that does not exist.\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.CanvasNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Canvas' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'chat-native') {\n // Opens the conversation list. Deliberately no channelId: the\n // uuid minted above is an AI-chat channel, not a messenger\n // channel, and passing it would read as a deep link into a\n // thread that does not exist.\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.ChatNative',\n params: { orgName: orgName ?? undefined },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'billing-native') {\n navigation.navigate('MainStack.Billing', { orgName: orgName ?? undefined });\n return;\n }\n\n if (app.nativeRoute === 'shopping-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.ShoppingNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Shop' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'travel-native') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.TravelNative',\n params: { orgName: orgName ?? undefined, appTitle: 'Travel' },\n }),\n );\n return;\n }\n\n if (app.nativeRoute === 'webbuilder') {\n const surfaceUrl = resolveSurfaceUrl(app, config);\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.WebBuilder',\n params: surfaceUrl ? { ...params, url: surfaceUrl } : params,\n }),\n );\n return;\n }\n\n void createChannel({\n id: channelId,\n title: buildChannelTitle(channelId),\n isShared: false,\n sharedSlug: null,\n isArchived: false,\n isPinned: false,\n model: null,\n systemPrompt: null,\n orgName,\n } as any).catch((err) => {\n console.error('[AppsCatalog] createChannel failed:', err);\n });\n\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.Chat',\n params: {\n ...params,\n initialQuery: app.prompt,\n initialMode: 'chat',\n },\n }),\n );\n },\n [createChannel, navigation, orgName],\n );\n\n return (\n <View style={[styles.root, { backgroundColor: screenBg }]}>\n <View style={[styles.searchWrap, { backgroundColor: fieldBg, borderColor }]}>\n <MaterialCommunityIcons name=\"magnify\" size={18} color={muted} />\n <TextInput\n value={query}\n onChangeText={setQuery}\n placeholder=\"Search apps\"\n placeholderTextColor={muted}\n autoCorrect={false}\n autoCapitalize=\"none\"\n style={[styles.searchInput, { color: foreground }]}\n />\n </View>\n <ScrollView keyboardShouldPersistTaps=\"handled\" contentContainerStyle={styles.list}>\n {grouped.length === 0 ? (\n <Text style={[styles.empty, { color: muted }]}>No apps match that search.</Text>\n ) : (\n grouped.map((group) => (\n <View key={group.label} style={styles.group}>\n <Text style={[styles.groupLabel, { color: muted }]}>{group.label}</Text>\n <View style={styles.groupGrid}>\n {group.items.map((app) => (\n <Pressable\n key={app.key}\n onPress={() => openApp(app)}\n accessibilityRole=\"button\"\n accessibilityLabel={app.label}\n style={({ pressed }) => [\n styles.appTile,\n {\n backgroundColor: surface,\n borderColor,\n },\n pressed && { backgroundColor: accentSoft },\n ]}\n >\n <View style={[styles.appIcon, { backgroundColor: accentSoft }]}>\n <MaterialCommunityIcons name={app.icon} size={18} color={accent} />\n </View>\n <Text style={[styles.appLabel, { color: foreground }]} numberOfLines={2}>\n {app.label}\n </Text>\n </Pressable>\n ))}\n </View>\n </View>\n ))\n )}\n </ScrollView>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1,\n },\n searchWrap: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 8,\n marginHorizontal: 16,\n marginTop: 12,\n marginBottom: 8,\n borderWidth: 1,\n borderRadius: 12,\n paddingHorizontal: 12,\n minHeight: 42,\n },\n searchInput: {\n flex: 1,\n fontSize: 15,\n paddingVertical: 8,\n },\n list: {\n paddingHorizontal: 16,\n paddingTop: 8,\n paddingBottom: 28,\n gap: 16,\n },\n group: {\n gap: 8,\n },\n groupLabel: {\n fontSize: 11,\n fontWeight: '600',\n letterSpacing: 0.7,\n textTransform: 'uppercase',\n },\n groupGrid: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n gap: 8,\n },\n appTile: {\n width: '31%',\n flexGrow: 1,\n minWidth: 96,\n maxWidth: '32.5%',\n borderWidth: 1,\n borderRadius: 14,\n paddingHorizontal: 10,\n paddingVertical: 12,\n gap: 8,\n },\n appIcon: {\n width: 32,\n height: 32,\n borderRadius: 10,\n alignItems: 'center',\n justifyContent: 'center',\n },\n appLabel: {\n fontSize: 13,\n fontWeight: '600',\n lineHeight: 17,\n },\n empty: {\n textAlign: 'center',\n paddingVertical: 28,\n fontSize: 14,\n },\n});\n"],"names":["_a","uuidv4"],"mappings":"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"}
@@ -206,6 +206,13 @@ const MOBILE_APP_CATALOG = [{
206
206
  // Federated storefront: search + cart download from shopping_native/Shop.
207
207
  // The classic Shop tile keeps the web surface in the WebView host.
208
208
  nativeRoute: "shopping-native"
209
+ }, {
210
+ key: "travel-native",
211
+ label: "Travel Native",
212
+ icon: "airplane-takeoff",
213
+ group: "More",
214
+ prompt: "Plan a 4-day trip for me: flights, somewhere to stay, and what to do each day.",
215
+ nativeRoute: "travel-native"
209
216
  }, {
210
217
  key: "travel",
211
218
  label: "Travel",