@adminide-stack/yantra-mobile 12.0.44-alpha.17 → 12.0.44-alpha.20
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/lib/components/KeyboardComposerDock.js +10 -1
- package/lib/components/KeyboardComposerDock.js.map +1 -1
- package/lib/components/NavigationHeader/NavigationHeader.js +15 -16
- package/lib/components/NavigationHeader/NavigationHeader.js.map +1 -1
- package/lib/features/apps/AppsCatalog.js +2 -1
- package/lib/features/apps/AppsCatalog.js.map +1 -1
- package/lib/features/apps/resolveSurfaceUrl.js +22 -2
- package/lib/features/apps/resolveSurfaceUrl.js.map +1 -1
- package/lib/features/attachments/ComposerAttachmentBar.js +64 -0
- package/lib/features/attachments/ComposerAttachmentBar.js.map +1 -0
- package/lib/features/attachments/MessageAttachmentPreviews.js +77 -0
- package/lib/features/attachments/MessageAttachmentPreviews.js.map +1 -0
- package/lib/features/attachments/attachmentPreviewUri.js +9 -0
- package/lib/features/attachments/attachmentPreviewUri.js.map +1 -0
- package/lib/features/attachments/buildGatewayMedia.js +118 -0
- package/lib/features/attachments/buildGatewayMedia.js.map +1 -0
- package/lib/features/attachments/composerAttachmentHandoff.js +15 -0
- package/lib/features/attachments/composerAttachmentHandoff.js.map +1 -0
- package/lib/features/attachments/displayUserMessageText.js +19 -0
- package/lib/features/attachments/displayUserMessageText.js.map +1 -0
- package/lib/features/attachments/historyAttachmentLabel.js +51 -0
- package/lib/features/attachments/historyAttachmentLabel.js.map +1 -0
- package/lib/features/attachments/isImageAttachment.js +7 -0
- package/lib/features/attachments/isImageAttachment.js.map +1 -0
- package/lib/features/attachments/preserveAttachmentPreviews.js +41 -0
- package/lib/features/attachments/preserveAttachmentPreviews.js.map +1 -0
- package/lib/features/attachments/uploadChatAttachments.js +102 -0
- package/lib/features/attachments/uploadChatAttachments.js.map +1 -0
- package/lib/features/attachments/useImageAttachments.js +102 -7
- package/lib/features/attachments/useImageAttachments.js.map +1 -1
- package/lib/features/canvas/nativeViewerRegistry.js +8 -1
- package/lib/features/canvas/nativeViewerRegistry.js.map +1 -1
- package/lib/features/canvas/surfaceIndex.js +25 -0
- package/lib/features/canvas/surfaceIndex.js.map +1 -0
- package/lib/features/canvas/useCanvasSession.js +57 -0
- package/lib/features/canvas/useCanvasSession.js.map +1 -0
- package/lib/features/chat/ChatTranscript.js +202 -0
- package/lib/features/chat/ChatTranscript.js.map +1 -0
- package/lib/hooks/useCdecliChannel.js +5 -3
- package/lib/hooks/useCdecliChannel.js.map +1 -1
- package/lib/hooks/useChatApi.js +32 -15
- package/lib/hooks/useChatApi.js.map +1 -1
- package/lib/hooks/useChatStream.js +35 -8
- package/lib/hooks/useChatStream.js.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/screens/CanvasBoard/index.js +20 -15
- package/lib/screens/CanvasBoard/index.js.map +1 -1
- package/lib/screens/Chat/index.js +39 -66
- package/lib/screens/Chat/index.js.map +1 -1
- package/lib/screens/ChatHistory/index.js +2 -8
- package/lib/screens/ChatHistory/index.js.map +1 -1
- package/lib/screens/Home/HomeScreen.js +57 -21
- package/lib/screens/Home/HomeScreen.js.map +1 -1
- package/lib/screens/Home/components/ChatHistoryLanding.js +15 -9
- package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -1
- package/lib/screens/WebBuilder/index.js.map +1 -1
- package/lib/utils/navigateToNewChatHome.js +40 -0
- package/lib/utils/navigateToNewChatHome.js.map +1 -0
- package/package.json +3 -3
- package/lib/features/canvas/canvasCore.js +0 -41
- package/lib/features/canvas/canvasCore.js.map +0 -1
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { Feature } from '@common-stack/client-react';\nimport YantraMobileModule from './module';\n\nexport default new Feature(YantraMobileModule);\nexport * from './screens';\nexport { GatewayContextProvider, useGatewayContext } from './contexts/GatewayContext';\nexport { CdecliConnectionProvider, useCdecliConnection } from './contexts/CdecliConnectionContext';\nexport * from './config/constants';\nexport { config } from './config/env-config';\nexport { useCdecliAutoConnect } from './hooks/useCdecliAutoConnect';\nexport { useObtainSystemToken } from './hooks/useObtainSystemToken';\nexport {\n mintSurfaceSystemToken,\n appendSurfaceAuthParams,\n buildCdecliTokenInjection,\n buildSurfaceGateRecoveryScript,\n resolveSurfaceCatalogBackend,\n resolveSurfaceAuthGraphqlUrl,\n} from './hooks/mintSurfaceSystemToken';\nexport { useGatewayConnection, isInstanceNotFoundError } from './hooks/useGatewayConnection';\nexport { usePrerequisiteIds } from './hooks/usePrerequisiteIds';\nexport { useWorkspaceProvisioner } from './hooks/useWorkspaceProvisioner';\nexport { useGatewayRegistry } from './hooks/useGatewayRegistry';\nexport * from './services';\nexport * from './bridge';\nexport {\n YantraBrandLoader,\n YANTRA_LOADER_SIZE_DEFAULT,\n YANTRA_LOADER_SIZE_COMPACT,\n} from './components/YantraBrandLoader';\nexport { default as CustomDrawer } from './components/CustomDrawer';\n// The canvas viewer seam. Exported from the index on purpose: the app (the MF\n// host) registers the federated viewer here and the CanvasBoard screen reads\n// it. Reachability from this entry is what makes rollup emit the registry as a\n// real shared module - as an internal-only file, `registerNativeCanvasViewer`\n// is never called inside the package, so rollup tree-shakes it and constant-\n// folds the screen down to its fallback branch.\nexport {
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { Feature } from '@common-stack/client-react';\nimport YantraMobileModule from './module';\n\nexport default new Feature(YantraMobileModule);\nexport * from './screens';\nexport { GatewayContextProvider, useGatewayContext } from './contexts/GatewayContext';\nexport { CdecliConnectionProvider, useCdecliConnection } from './contexts/CdecliConnectionContext';\nexport * from './config/constants';\nexport { config } from './config/env-config';\nexport { useCdecliAutoConnect } from './hooks/useCdecliAutoConnect';\nexport { useObtainSystemToken } from './hooks/useObtainSystemToken';\nexport {\n mintSurfaceSystemToken,\n appendSurfaceAuthParams,\n buildCdecliTokenInjection,\n buildSurfaceGateRecoveryScript,\n resolveSurfaceCatalogBackend,\n resolveSurfaceAuthGraphqlUrl,\n} from './hooks/mintSurfaceSystemToken';\nexport { useGatewayConnection, isInstanceNotFoundError } from './hooks/useGatewayConnection';\nexport { usePrerequisiteIds } from './hooks/usePrerequisiteIds';\nexport { useWorkspaceProvisioner } from './hooks/useWorkspaceProvisioner';\nexport { useGatewayRegistry } from './hooks/useGatewayRegistry';\nexport * from './services';\nexport * from './bridge';\nexport {\n YantraBrandLoader,\n YANTRA_LOADER_SIZE_DEFAULT,\n YANTRA_LOADER_SIZE_COMPACT,\n} from './components/YantraBrandLoader';\nexport { default as CustomDrawer } from './components/CustomDrawer';\n// The canvas viewer seam. Exported from the index on purpose: the app (the MF\n// host) registers the federated viewer here and the CanvasBoard screen reads\n// it. Reachability from this entry is what makes rollup emit the registry as a\n// real shared module - as an internal-only file, `registerNativeCanvasViewer`\n// is never called inside the package, so rollup tree-shakes it and constant-\n// folds the screen down to its fallback branch.\nexport {\n registerNativeCanvasViewer,\n getNativeCanvasViewer,\n registerNativeCanvasExperience,\n getNativeCanvasExperience,\n} from './features/canvas/nativeViewerRegistry';\n"],"names":[],"mappings":"g0FAEA,YAAe,IAAI,QAAQ,kBAAkB,CAAA"}
|
|
@@ -1,25 +1,30 @@
|
|
|
1
|
-
import {jsx,jsxs}from'react/jsx-runtime';import {
|
|
2
|
-
version: 1,
|
|
3
|
-
savedAt: 0,
|
|
4
|
-
items: [],
|
|
5
|
-
zoom: 1
|
|
6
|
-
};
|
|
7
|
-
function CanvasBoardScreen() {
|
|
1
|
+
import {jsx,jsxs}from'react/jsx-runtime';import {useColorScheme,StyleSheet,View,Text}from'react-native';import {SafeAreaView}from'react-native-safe-area-context';import {useRoute}from'@react-navigation/native';import {getNativeCanvasExperience}from'../../features/canvas/nativeViewerRegistry.js';import {useCanvasSession}from'../../features/canvas/useCanvasSession.js';function CanvasBoardScreen() {
|
|
8
2
|
const route = useRoute();
|
|
9
3
|
const isDark = useColorScheme() === "dark";
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
const Experience = getNativeCanvasExperience();
|
|
5
|
+
const {
|
|
6
|
+
token,
|
|
7
|
+
indexUrl,
|
|
8
|
+
error,
|
|
9
|
+
ready
|
|
10
|
+
} = useCanvasSession();
|
|
11
|
+
const params = route.params;
|
|
12
|
+
const channelId = typeof (params == null ? void 0 : params.channelId) === "string" ? params.channelId : void 0;
|
|
13
|
+
if (!Experience) {
|
|
17
14
|
return /* @__PURE__ */ jsx(SafeAreaView, { style: [styles.fill, isDark && styles.fillDark], children: /* @__PURE__ */ jsxs(View, { style: styles.center, children: [
|
|
18
15
|
/* @__PURE__ */ jsx(Text, { style: [styles.title, isDark && styles.textLight], children: "Native canvas unavailable" }),
|
|
19
16
|
/* @__PURE__ */ jsx(Text, { style: [styles.detail, isDark && styles.textMuted], children: "This build does not carry the federation host runtime." })
|
|
20
17
|
] }) });
|
|
21
18
|
}
|
|
22
|
-
return /* @__PURE__ */ jsx(SafeAreaView, { style: [styles.fill, isDark && styles.fillDark], edges: ["left", "right", "bottom"], children: /* @__PURE__ */ jsx(
|
|
19
|
+
return /* @__PURE__ */ jsx(SafeAreaView, { style: [styles.fill, isDark && styles.fillDark], edges: ["left", "right", "bottom"], children: /* @__PURE__ */ jsx(
|
|
20
|
+
Experience,
|
|
21
|
+
{
|
|
22
|
+
token,
|
|
23
|
+
indexUrl,
|
|
24
|
+
channelId,
|
|
25
|
+
sessionError: ready ? error : null
|
|
26
|
+
}
|
|
27
|
+
) });
|
|
23
28
|
}
|
|
24
29
|
const styles = StyleSheet.create({
|
|
25
30
|
fill: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/screens/CanvasBoard/index.tsx"],"sourcesContent":["/**\n * Native canvas board screen
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/screens/CanvasBoard/index.tsx"],"sourcesContent":["/**\n * Native canvas board screen.\n *\n * The screen is deliberately thin. Opening it triggers the federated fetch of\n * the canvas remote, and the remote owns everything after that: reading the\n * user's boards from the SurfaceChannel index, choosing one, and rendering it.\n * That split is what lets a canvas change ship with `cdecli surfaces deploy\n * canvas` instead of an App Store release.\n *\n * The host contributes the two things the remote cannot know: a token the index\n * accepts, and the index endpoint for this environment.\n */\nimport React from 'react';\nimport { StyleSheet, Text, View, useColorScheme } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { useRoute } from '@react-navigation/native';\nimport { getNativeCanvasExperience } from '../../features/canvas/nativeViewerRegistry';\nimport { useCanvasSession } from '../../features/canvas/useCanvasSession';\n\nexport interface CanvasBoardRouteParams {\n /** Open a specific board from the index; otherwise the newest one opens. */\n channelId?: string;\n}\n\nexport default function CanvasBoardScreen() {\n const route = useRoute();\n const isDark = useColorScheme() === 'dark';\n const Experience = getNativeCanvasExperience();\n const { token, indexUrl, error, ready } = useCanvasSession();\n\n const params = route.params as CanvasBoardRouteParams | undefined;\n const channelId = typeof params?.channelId === 'string' ? params.channelId : undefined;\n\n if (!Experience) {\n // A build without the federation host (or before App registered it).\n // Say so instead of rendering a blank screen.\n return (\n <SafeAreaView style={[styles.fill, isDark && styles.fillDark]}>\n <View style={styles.center}>\n <Text style={[styles.title, isDark && styles.textLight]}>Native canvas unavailable</Text>\n <Text style={[styles.detail, isDark && styles.textMuted]}>\n This build does not carry the federation host runtime.\n </Text>\n </View>\n </SafeAreaView>\n );\n }\n\n return (\n <SafeAreaView style={[styles.fill, isDark && styles.fillDark]} edges={['left', 'right', 'bottom']}>\n <Experience\n token={token}\n indexUrl={indexUrl}\n channelId={channelId}\n // Until the mint settles, `sessionError` stays null so the remote\n // shows its loading state rather than flashing a failure.\n sessionError={ready ? error : null}\n />\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n fill: { flex: 1, backgroundColor: '#f8fafc' },\n fillDark: { backgroundColor: '#0f172a' },\n center: { flex: 1, alignItems: 'center', justifyContent: 'center', padding: 24 },\n title: { fontSize: 15, fontWeight: '600', color: '#0f172a', marginBottom: 6 },\n detail: { fontSize: 13, color: '#64748b', textAlign: 'center' },\n textLight: { color: '#f8fafc' },\n textMuted: { color: '#94a3b8' },\n});\n"],"names":[],"mappings":"iXAsBA,SAAwB,iBAAoB,GAAA;AAC1C,EAAA,MAAM,QAAQ,QAAS,EAAA;AACvB,EAAM,MAAA,MAAA,GAAS,gBAAqB,KAAA,MAAA;AACpC,EAAA,MAAM,aAAa,yBAA0B,EAAA;AAC7C,EAAM,MAAA;AAAA,IACJ,KAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,MACE,gBAAiB,EAAA;AACrB,EAAA,MAAM,SAAS,KAAM,CAAA,MAAA;AACrB,EAAA,MAAM,YAAY,QAAO,MAAA,IAAA,IAAA,GAAA,MAAA,GAAA,MAAA,CAAQ,SAAc,CAAA,KAAA,QAAA,GAAW,OAAO,SAAY,GAAA,MAAA;AAC7E,EAAA,IAAI,CAAC,UAAY,EAAA;AAGf,IAAA,uBAAQ,GAAA,CAAA,YAAA,EAAA,EAAa,KAAO,EAAA,CAAC,OAAO,IAAM,EAAA,MAAA,IAAU,MAAO,CAAA,QAAQ,CACvD,EAAA,QAAA,kBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,OAAO,MAChB,EAAA,QAAA,EAAA;AAAA,sBAAC,GAAA,CAAA,IAAA,EAAA,EAAK,OAAO,CAAC,MAAA,CAAO,OAAO,MAAU,IAAA,MAAA,CAAO,SAAS,CAAA,EAAG,QAAyB,EAAA,2BAAA,EAAA,CAAA;AAAA,sBAClF,GAAA,CAAC,IAAK,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,QAAQ,MAAU,IAAA,MAAA,CAAO,SAAS,CAAA,EAAG,QAE1D,EAAA,wDAAA,EAAA;AAAA,KAAA,EACJ,CACJ,EAAA,CAAA;AAAA;AAEV,EAAA,uBAAQ,GAAA,CAAA,YAAA,EAAA,EAAa,KAAO,EAAA,CAAC,OAAO,IAAM,EAAA,MAAA,IAAU,MAAO,CAAA,QAAQ,GAAG,KAAO,EAAA,CAAC,MAAQ,EAAA,OAAA,EAAS,QAAQ,CAC7F,EAAA,QAAA,kBAAA,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MAAW,KAAA;AAAA,MAAc,QAAA;AAAA,MAAoB,SAAA;AAAA,MAGtD,YAAA,EAAc,QAAQ,KAAQ,GAAA;AAAA;AAAA,GAC1B,EAAA,CAAA;AACR;AACA,MAAM,MAAA,GAAS,WAAW,MAAO,CAAA;AAAA,EAC/B,IAAM,EAAA;AAAA,IACJ,IAAM,EAAA,CAAA;AAAA,IACN,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,QAAU,EAAA;AAAA,IACR,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,CAAA;AAAA,IACN,UAAY,EAAA,QAAA;AAAA,IACZ,cAAgB,EAAA,QAAA;AAAA,IAChB,OAAS,EAAA;AAAA,GACX;AAAA,EACA,KAAO,EAAA;AAAA,IACL,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,KAAA;AAAA,IACZ,KAAO,EAAA,SAAA;AAAA,IACP,YAAc,EAAA;AAAA,GAChB;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,QAAU,EAAA,EAAA;AAAA,IACV,KAAO,EAAA,SAAA;AAAA,IACP,SAAW,EAAA;AAAA,GACb;AAAA,EACA,SAAW,EAAA;AAAA,IACT,KAAO,EAAA;AAAA,GACT;AAAA,EACA,SAAW,EAAA;AAAA,IACT,KAAO,EAAA;AAAA;AAEX,CAAC,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {jsx,jsxs}from'react/jsx-runtime';import {useMemo,useEffect,useCallback,useState,useRef}from'react';import {useColorScheme,useWindowDimensions,Keyboard,
|
|
1
|
+
import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useMemo,useEffect,useCallback,useState,useRef}from'react';import {useColorScheme,useWindowDimensions,Keyboard,StyleSheet,View}from'react-native';import {getDefaultLeftItems,getDefaultRightItems,Box,Text,InputToolBar}from'@admin-layout/gluestack-ui-mobile';import {useSafeAreaInsets,SafeAreaView}from'react-native-safe-area-context';import {useNavigation,useRoute,CommonActions}from'@react-navigation/native';import {MessageActionBar}from'../../features/chat/MessageActionBar.js';import {ChatTranscript}from'../../features/chat/ChatTranscript.js';import {useCdecliConnection}from'../../contexts/CdecliConnectionContext.js';import {useChatStream}from'../../hooks/useChatStream.js';import {useKeyboardBottomOffset}from'../../hooks/useKeyboardBottomOffset.js';import {KeyboardComposerDock}from'../../components/KeyboardComposerDock.js';import {YantraBrandLoader,YANTRA_LOADER_SIZE_COMPACT}from'../../components/YantraBrandLoader.js';import ThinkingIndicator from'../../components/ThinkingIndicator.js';import {mobileTokens}from'../../theme/mobileTokens.js';import DeepSearchModal from'../Home/components/DeepSearchModal.js';import {normalizeSummaryText,extractDeepSearchSources}from'../Home/deepSearchUtils.js';import {AudioRecorderPanel}from'../../features/audio-input/AudioRecorderPanel.js';import {useImageAttachments}from'../../features/attachments/useImageAttachments.js';import {ComposerAttachmentBar}from'../../features/attachments/ComposerAttachmentBar.js';import {hasComposerAttachments,takeComposerAttachments}from'../../features/attachments/composerAttachmentHandoff.js';import {MicErrorBoundary}from'../../features/audio-input/MicErrorBoundary.js';import {requestMicPermission}from'../../features/audio-input/useAudioPermission.js';var __defProp = Object.defineProperty;
|
|
2
2
|
var __defProps = Object.defineProperties;
|
|
3
3
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
@@ -17,10 +17,6 @@ var __spreadValues = (a, b) => {
|
|
|
17
17
|
return a;
|
|
18
18
|
};
|
|
19
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
const CHAT_CURRENT_USER = {
|
|
21
|
-
id: "user"
|
|
22
|
-
};
|
|
23
|
-
const renderNoToolbar = () => null;
|
|
24
20
|
function ChatScreen() {
|
|
25
21
|
var _a, _b;
|
|
26
22
|
const navigation = useNavigation();
|
|
@@ -45,7 +41,6 @@ function ChatScreen() {
|
|
|
45
41
|
const secondaryTextColor = isDark ? "#94a3b8" : mobileTokens.color.textMuted;
|
|
46
42
|
const insets = useSafeAreaInsets();
|
|
47
43
|
const {
|
|
48
|
-
keyboardHeight,
|
|
49
44
|
keyboardVisible
|
|
50
45
|
} = useKeyboardBottomOffset();
|
|
51
46
|
const cdecli = useCdecliConnection();
|
|
@@ -67,6 +62,7 @@ function ChatScreen() {
|
|
|
67
62
|
id: `msg-${index}-${msg.role}`,
|
|
68
63
|
role: msg.role,
|
|
69
64
|
content: msg.content,
|
|
65
|
+
attachments: msg.attachments,
|
|
70
66
|
metadata: msg.metadata
|
|
71
67
|
})), [chat.messages]);
|
|
72
68
|
const {
|
|
@@ -80,22 +76,19 @@ function ChatScreen() {
|
|
|
80
76
|
cancel
|
|
81
77
|
} = chat;
|
|
82
78
|
const regenerateFrom = useCallback((messageId) => {
|
|
83
|
-
var _a2;
|
|
79
|
+
var _a2, _b2;
|
|
84
80
|
const match = /^msg-(\d+)-assistant$/.exec(messageId);
|
|
85
81
|
if (!match || !channelId) return;
|
|
86
82
|
for (let i = Number(match[1]) - 1; i >= 0; i -= 1) {
|
|
87
83
|
const prior = chat.messages[i];
|
|
88
|
-
if ((prior == null ? void 0 : prior.role) === "user" && ((_a2 = prior.content) == null ? void 0 : _a2.trim())) {
|
|
89
|
-
void chat.sendMessage(prior.content,
|
|
84
|
+
if ((prior == null ? void 0 : prior.role) === "user" && (((_a2 = prior.content) == null ? void 0 : _a2.trim()) || ((_b2 = prior.attachments) == null ? void 0 : _b2.length))) {
|
|
85
|
+
void chat.sendMessage(prior.content, prior.attachments, channelId);
|
|
90
86
|
return;
|
|
91
87
|
}
|
|
92
88
|
}
|
|
93
89
|
}, [chat, channelId]);
|
|
94
90
|
const chatBusy = isLoading || isStreaming;
|
|
95
91
|
const renderMessageActions = useCallback((message) => message.role === "assistant" ? /* @__PURE__ */ jsx(MessageActionBar, { text: message.content, onRegenerate: chatBusy ? void 0 : () => regenerateFrom(message.id) }) : null, [chatBusy, regenerateFrom]);
|
|
96
|
-
const messageActionsSlot = {
|
|
97
|
-
renderMessageActions
|
|
98
|
-
};
|
|
99
92
|
const imageAttachments = useImageAttachments();
|
|
100
93
|
const [value, setValue] = useState("");
|
|
101
94
|
const valueRef = useRef(value);
|
|
@@ -103,7 +96,8 @@ function ChatScreen() {
|
|
|
103
96
|
const inputRef = useRef(null);
|
|
104
97
|
const trimmed = value.trim();
|
|
105
98
|
const hasQuery = trimmed.length > 0;
|
|
106
|
-
const
|
|
99
|
+
const hasAttachments = imageAttachments.pending.length > 0;
|
|
100
|
+
const canSubmit = (hasQuery || hasAttachments) && Boolean(channelId);
|
|
107
101
|
const [activeMode, setActiveMode] = useState(() => params.initialMode === "deep-search" ? "deep-search" : params.initialMode === "build" ? "build" : "chat");
|
|
108
102
|
const handleModeSwitch = useCallback((mode) => {
|
|
109
103
|
setActiveMode(mode);
|
|
@@ -115,13 +109,15 @@ function ChatScreen() {
|
|
|
115
109
|
const autoFiredRef = useRef(false);
|
|
116
110
|
useEffect(() => {
|
|
117
111
|
if (autoFiredRef.current) return;
|
|
118
|
-
if (!channelId
|
|
112
|
+
if (!channelId) return;
|
|
119
113
|
if (cdecli.status !== "connected" && cdecli.status !== "error") return;
|
|
114
|
+
const stashed = hasComposerAttachments(channelId) ? takeComposerAttachments(channelId) : void 0;
|
|
115
|
+
if (!initialQuery && !(stashed == null ? void 0 : stashed.length)) return;
|
|
120
116
|
autoFiredRef.current = true;
|
|
121
117
|
if (isDeepSearchMode) {
|
|
122
118
|
setIsDeepSearchModalOpen(true);
|
|
123
119
|
}
|
|
124
|
-
void sendMessage(initialQuery,
|
|
120
|
+
void sendMessage(initialQuery != null ? initialQuery : "", stashed, channelId);
|
|
125
121
|
try {
|
|
126
122
|
navigation.setParams({
|
|
127
123
|
initialQuery: null,
|
|
@@ -132,8 +128,9 @@ function ChatScreen() {
|
|
|
132
128
|
}, [channelId, initialQuery, initialAttachments, sendMessage, navigation, cdecli.status, isDeepSearchMode]);
|
|
133
129
|
const handleSend = useCallback((text) => {
|
|
134
130
|
var _a2;
|
|
131
|
+
const pending = imageAttachments.forSend();
|
|
135
132
|
const t = (text != null ? text : valueRef.current).trim();
|
|
136
|
-
if (!t || !channelId) return;
|
|
133
|
+
if (!t && !(pending == null ? void 0 : pending.length) || !channelId) return;
|
|
137
134
|
setValue("");
|
|
138
135
|
(_a2 = inputRef.current) == null ? void 0 : _a2.clear();
|
|
139
136
|
if (isBuildMode) {
|
|
@@ -151,7 +148,7 @@ function ChatScreen() {
|
|
|
151
148
|
if (isDeepSearchMode) {
|
|
152
149
|
setIsDeepSearchModalOpen(true);
|
|
153
150
|
}
|
|
154
|
-
void sendMessage(t,
|
|
151
|
+
void sendMessage(t, pending, channelId);
|
|
155
152
|
imageAttachments.clear();
|
|
156
153
|
}, [channelId, sendMessage, isDeepSearchMode, isBuildMode, navigation, params.orgName, imageAttachments]);
|
|
157
154
|
const handleValueChange = useCallback((e) => {
|
|
@@ -202,7 +199,6 @@ function ChatScreen() {
|
|
|
202
199
|
if ((response != null ? response : "").trim()) return false;
|
|
203
200
|
return ((_a2 = messages[messages.length - 1]) == null ? void 0 : _a2.role) === "user";
|
|
204
201
|
}, [isLoading, isStreaming, messages, response]);
|
|
205
|
-
const composerScrollBottomPadding = 24 + (keyboardVisible ? keyboardHeight : 0);
|
|
206
202
|
const [isDeepSearchModalOpen, setIsDeepSearchModalOpen] = useState(false);
|
|
207
203
|
const [researchProcessOpen, setResearchProcessOpen] = useState(true);
|
|
208
204
|
const [sourcesAccordionOpen, setSourcesAccordionOpen] = useState(true);
|
|
@@ -269,20 +265,24 @@ function ChatScreen() {
|
|
|
269
265
|
// dependency with its permission strings declared in app.json.
|
|
270
266
|
camera: {
|
|
271
267
|
enabled: true,
|
|
272
|
-
loading: imageAttachments.
|
|
268
|
+
loading: imageAttachments.busyKind === "camera",
|
|
273
269
|
onClick: () => {
|
|
274
270
|
void imageAttachments.captureFromCamera();
|
|
275
271
|
}
|
|
276
272
|
},
|
|
277
273
|
image: {
|
|
278
274
|
enabled: true,
|
|
279
|
-
loading: imageAttachments.
|
|
275
|
+
loading: imageAttachments.busyKind === "library",
|
|
280
276
|
onClick: () => {
|
|
281
277
|
void imageAttachments.pickFromLibrary();
|
|
282
278
|
}
|
|
283
279
|
},
|
|
284
280
|
attach: {
|
|
285
|
-
enabled:
|
|
281
|
+
enabled: true,
|
|
282
|
+
loading: imageAttachments.busyKind === "documents",
|
|
283
|
+
onClick: () => {
|
|
284
|
+
void imageAttachments.pickDocuments();
|
|
285
|
+
}
|
|
286
286
|
}
|
|
287
287
|
}), [imageAttachments]);
|
|
288
288
|
const inputPlaceholder = isDeepSearchMode ? "Research anything..." : isBuildMode ? "Describe an app to build..." : "Ask anything...";
|
|
@@ -297,7 +297,7 @@ function ChatScreen() {
|
|
|
297
297
|
onSubmitEditing: () => handleSend()
|
|
298
298
|
}), [value, handleValueChange, inputPlaceholder, channelId, handleSend]);
|
|
299
299
|
const micSendButton = useMemo(() => ({
|
|
300
|
-
hasContent: hasQuery,
|
|
300
|
+
hasContent: hasQuery || hasAttachments,
|
|
301
301
|
onSend: () => handleSend(),
|
|
302
302
|
onMic: handleMicPress,
|
|
303
303
|
disabled: !channelId,
|
|
@@ -305,16 +305,16 @@ function ChatScreen() {
|
|
|
305
305
|
isLoading: canSubmit ? false : isLoading,
|
|
306
306
|
onStop: isStreaming && !canSubmit ? cancel : void 0,
|
|
307
307
|
steerable: isLoading || isStreaming
|
|
308
|
-
}), [canSubmit, handleSend, handleMicPress, isLoading, channelId, isStreaming, cancel, hasQuery]);
|
|
308
|
+
}), [canSubmit, handleSend, handleMicPress, isLoading, channelId, isStreaming, cancel, hasQuery, hasAttachments]);
|
|
309
309
|
const isHydrating = messagesLoading && messages.length === 0 && !response;
|
|
310
|
-
const isWaitingForGateway = !autoFiredRef.current && !!channelId && !!initialQuery && cdecli.status !== "connected" && cdecli.status !== "error";
|
|
310
|
+
const isWaitingForGateway = !autoFiredRef.current && !!channelId && (!!initialQuery || hasComposerAttachments(channelId)) && cdecli.status !== "connected" && cdecli.status !== "error";
|
|
311
311
|
const showSendingLoader = waitingForAssistant;
|
|
312
312
|
const pinSendingLoaderNearComposer = messages.length > 0 || Boolean((response != null ? response : "").trim());
|
|
313
313
|
return /* @__PURE__ */ jsxs(SafeAreaView, { edges: ["left", "right"], style: {
|
|
314
314
|
flex: 1,
|
|
315
315
|
backgroundColor: surfaceColor
|
|
316
316
|
}, children: [
|
|
317
|
-
/* @__PURE__ */
|
|
317
|
+
/* @__PURE__ */ jsxs(Box, { flex: 1, width: "100%", position: "relative", children: [
|
|
318
318
|
(chatError || cdecli.error) && /* @__PURE__ */ jsx(Box, { mb: "$2", mx: "$4", p: "$3", borderRadius: "$md", style: {
|
|
319
319
|
backgroundColor: isDark ? "#2b1a1d" : "#fef2f2",
|
|
320
320
|
borderWidth: 1,
|
|
@@ -342,55 +342,25 @@ function ChatScreen() {
|
|
|
342
342
|
/* @__PURE__ */ jsx(Text, { style: [styles.statusText, {
|
|
343
343
|
color: secondaryTextColor
|
|
344
344
|
}], children: "Connecting gateway\u2026" })
|
|
345
|
-
] }) : /* @__PURE__ */ jsx(Box, { flex: 1, width: "100%", alignSelf: "stretch", children: /* @__PURE__ */ jsx(
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
}, messageActionsSlot), {
|
|
353
|
-
messagesContainerStyle: {
|
|
354
|
-
paddingHorizontal: 0,
|
|
355
|
-
paddingTop: 0,
|
|
356
|
-
paddingBottom: composerScrollBottomPadding,
|
|
357
|
-
margin: 0,
|
|
358
|
-
marginTop: 0,
|
|
359
|
-
alignSelf: "center",
|
|
360
|
-
width: contentMaxWidth
|
|
361
|
-
},
|
|
362
|
-
listContentStyle: {
|
|
363
|
-
paddingTop: 0,
|
|
364
|
-
paddingBottom: composerScrollBottomPadding,
|
|
365
|
-
margin: 0,
|
|
366
|
-
marginTop: 0,
|
|
367
|
-
width: contentMaxWidth,
|
|
368
|
-
alignSelf: "center",
|
|
369
|
-
justifyContent: "flex-end"
|
|
370
|
-
},
|
|
371
|
-
messages: transcriptRows,
|
|
372
|
-
streamingContent: response,
|
|
373
|
-
currentUser: CHAT_CURRENT_USER,
|
|
374
|
-
onSend: handleSend,
|
|
375
|
-
disabled: !channelId,
|
|
376
|
-
isLoading,
|
|
377
|
-
onStop: isStreaming ? cancel : void 0,
|
|
378
|
-
renderPlanInputToolbar: renderNoToolbar,
|
|
379
|
-
renderBuildInputToolbar: renderNoToolbar
|
|
380
|
-
})
|
|
381
|
-
) }),
|
|
345
|
+
] }) : /* @__PURE__ */ jsx(Box, { flex: 1, width: "100%", alignSelf: "stretch", children: /* @__PURE__ */ jsx(ChatTranscript, { messages: transcriptRows, streamingContent: response, renderMessageActions, isDark, keyboardVisible, listContentStyle: {
|
|
346
|
+
paddingTop: 12,
|
|
347
|
+
paddingBottom: 8,
|
|
348
|
+
margin: 0,
|
|
349
|
+
width: contentMaxWidth,
|
|
350
|
+
alignSelf: "center"
|
|
351
|
+
} }) }),
|
|
382
352
|
showSendingLoader && !pinSendingLoaderNearComposer ? /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: styles.sendingLoaderEmptyState, children: /* @__PURE__ */ jsx(ThinkingIndicator, { color: secondaryTextColor }) }) : null,
|
|
383
353
|
/* @__PURE__ */ jsxs(KeyboardComposerDock, { closedInset: insets.bottom, keyboardVisible, children: [
|
|
384
354
|
showSendingLoader && pinSendingLoaderNearComposer ? /* @__PURE__ */ jsx(View, { pointerEvents: "none", style: styles.sendingLoaderInDock, children: /* @__PURE__ */ jsx(ThinkingIndicator, { color: secondaryTextColor }) }) : null,
|
|
385
355
|
/* @__PURE__ */ jsxs(View, { style: [styles.bottomComposerInner, {
|
|
386
356
|
width: contentMaxWidth
|
|
387
357
|
}], children: [
|
|
388
|
-
voiceError ? /* @__PURE__ */ jsx(View, { style: [styles.voiceErrorBanner, {
|
|
358
|
+
voiceError || imageAttachments.error ? /* @__PURE__ */ jsx(View, { style: [styles.voiceErrorBanner, {
|
|
389
359
|
backgroundColor: isDark ? "#2b1a1d" : "#fef2f2",
|
|
390
360
|
borderColor: isDark ? "#7f1d1d" : "#fecaca"
|
|
391
361
|
}], children: /* @__PURE__ */ jsx(Text, { style: [styles.voiceErrorText, {
|
|
392
362
|
color: isDark ? "#fecaca" : "#991b1b"
|
|
393
|
-
}], children: voiceError }) }) : null,
|
|
363
|
+
}], children: voiceError || imageAttachments.error }) }) : null,
|
|
394
364
|
showAudioRecorder ? (
|
|
395
365
|
/*
|
|
396
366
|
* Render-time JS errors thrown by `useAudioRecorder`
|
|
@@ -403,10 +373,13 @@ function ChatScreen() {
|
|
|
403
373
|
* release / TestFlight.
|
|
404
374
|
*/
|
|
405
375
|
/* @__PURE__ */ jsx(MicErrorBoundary, { onCancel: handleRecorderCancel, onError: handleRecorderError, children: /* @__PURE__ */ jsx(AudioRecorderPanel, { isDark, onTranscriptionComplete: handleTranscriptionComplete, onCancel: handleRecorderCancel, onError: handleRecorderError }) })
|
|
406
|
-
) : /* @__PURE__ */
|
|
376
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
377
|
+
/* @__PURE__ */ jsx(ComposerAttachmentBar, { attachments: imageAttachments.pending, onRemove: imageAttachments.remove, isDark }),
|
|
378
|
+
/* @__PURE__ */ jsx(InputToolBar, { inputConfig, leftItems, rightItems, templateButton: null, templateModalConfig: null, micSendButton })
|
|
379
|
+
] })
|
|
407
380
|
] })
|
|
408
381
|
] })
|
|
409
|
-
] })
|
|
382
|
+
] }),
|
|
410
383
|
isDeepSearchMode ? /* @__PURE__ */ jsx(DeepSearchModal, { visible: isDeepSearchModalOpen, query: deepSearchQuery, summaryText: deepSearchSummary, sources: deepSearchSources, isStreaming, researchProcessOpen, sourcesAccordionOpen, onToggleResearchProcess: () => setResearchProcessOpen((prev) => !prev), onToggleSourcesAccordion: () => setSourcesAccordionOpen((prev) => !prev), onRetry: handleDeepSearchRetry, onStop: cancel, onClose: handleDeepSearchClose }) : null
|
|
411
384
|
] });
|
|
412
385
|
}
|