@adminide-stack/yantra-mobile 12.0.28-alpha.8 → 12.0.28-alpha.80
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/api/stt.js +54 -0
- package/lib/api/stt.js.map +1 -0
- package/lib/assets/icon.png +0 -0
- package/lib/components/CustomDrawer.js +479 -0
- package/lib/components/CustomDrawer.js.map +1 -0
- package/lib/components/GatewayConnector/GatewayConnector.js +18 -0
- package/lib/components/GatewayConnector/GatewayConnector.js.map +1 -0
- package/lib/components/GatewayToolbarButtonMobile.js +84 -0
- package/lib/components/GatewayToolbarButtonMobile.js.map +1 -0
- package/lib/components/NavigationHeader/NavigationHeader.js +214 -0
- package/lib/components/NavigationHeader/NavigationHeader.js.map +1 -0
- package/lib/components/ThinkingIndicator.js +55 -0
- package/lib/components/ThinkingIndicator.js.map +1 -0
- package/lib/components/YantraBrandLoader.js +94 -0
- package/lib/components/YantraBrandLoader.js.map +1 -0
- package/lib/compute.js +114 -5
- package/lib/compute.js.map +1 -1
- package/lib/config/constants.js +18 -0
- package/lib/config/constants.js.map +1 -0
- package/lib/config/env-config.js +75 -19
- package/lib/config/env-config.js.map +1 -1
- package/lib/contexts/CdecliConnectionContext.js +47 -0
- package/lib/contexts/CdecliConnectionContext.js.map +1 -0
- package/lib/contexts/GatewayContext.js +77 -0
- package/lib/contexts/GatewayContext.js.map +1 -0
- package/lib/features/audio-input/AudioRecorderPanel.js +220 -0
- package/lib/features/audio-input/AudioRecorderPanel.js.map +1 -0
- package/lib/features/audio-input/MicErrorBoundary.js +34 -0
- package/lib/features/audio-input/MicErrorBoundary.js.map +1 -0
- package/lib/features/audio-input/useAudioPermission.js +24 -0
- package/lib/features/audio-input/useAudioPermission.js.map +1 -0
- package/lib/graphql/agentGatewayDocuments.js +53 -0
- package/lib/graphql/agentGatewayDocuments.js.map +1 -0
- package/lib/hooks/useAccountDefaultSettings.js +38 -0
- package/lib/hooks/useAccountDefaultSettings.js.map +1 -0
- package/lib/hooks/useCdecliAutoConnect.js +244 -0
- package/lib/hooks/useCdecliAutoConnect.js.map +1 -0
- package/lib/hooks/useCdecliChannel.js +161 -0
- package/lib/hooks/useCdecliChannel.js.map +1 -0
- package/lib/hooks/useChatApi.js +390 -171
- package/lib/hooks/useChatApi.js.map +1 -1
- package/lib/hooks/useChatStream.js +179 -137
- package/lib/hooks/useChatStream.js.map +1 -1
- package/lib/hooks/useGatewayConnection.js +123 -0
- package/lib/hooks/useGatewayConnection.js.map +1 -0
- package/lib/hooks/useGatewayRegistry.js +28 -0
- package/lib/hooks/useGatewayRegistry.js.map +1 -0
- package/lib/hooks/usePrerequisiteIds.js +209 -0
- package/lib/hooks/usePrerequisiteIds.js.map +1 -0
- package/lib/hooks/useWorkspaceProvisioner.js +236 -0
- package/lib/hooks/useWorkspaceProvisioner.js.map +1 -0
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/routes.json +120 -5
- package/lib/screens/Chat/index.js +409 -0
- package/lib/screens/Chat/index.js.map +1 -0
- package/lib/screens/ChatHistory/index.js +56 -0
- package/lib/screens/ChatHistory/index.js.map +1 -0
- package/lib/screens/Home/HomeScreen.js +364 -144
- package/lib/screens/Home/HomeScreen.js.map +1 -1
- package/lib/screens/Home/components/ChatHistoryLanding.js +487 -0
- package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -0
- package/lib/screens/Home/components/DeepSearchModal.js +349 -0
- package/lib/screens/Home/components/DeepSearchModal.js.map +1 -0
- package/lib/screens/Home/deepSearchUtils.js +41 -0
- package/lib/screens/Home/deepSearchUtils.js.map +1 -0
- package/lib/screens/NewChat/index.js +43 -0
- package/lib/screens/NewChat/index.js.map +1 -0
- package/lib/services/agentSessionManager.js +451 -0
- package/lib/services/agentSessionManager.js.map +1 -0
- package/lib/services/gatewayApiKeyBridge.js +4 -0
- package/lib/services/gatewayApiKeyBridge.js.map +1 -0
- package/lib/services/gatewayClient.js +470 -0
- package/lib/services/gatewayClient.js.map +1 -0
- package/lib/theme/mobileTokens.js +18 -0
- package/lib/theme/mobileTokens.js.map +1 -0
- package/lib/utils/cdecodeUri.js +68 -0
- package/lib/utils/cdecodeUri.js.map +1 -0
- package/lib/utils/gatewaySelectionStorage.js +21 -0
- package/lib/utils/gatewaySelectionStorage.js.map +1 -0
- package/lib/utils/syncMobileOrgRouteContext.js +61 -0
- package/lib/utils/syncMobileOrgRouteContext.js.map +1 -0
- package/package.json +7 -3
- package/lib/api/chatApi.js +0 -102
- package/lib/api/chatApi.js.map +0 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {jsx}from'react/jsx-runtime';import React,{useCallback}from'react';import {useCdecliConnection}from'../../contexts/CdecliConnectionContext.js';import {GatewayToolbarButtonMobile}from'../GatewayToolbarButtonMobile.js';function mapCdecliStatus(status) {
|
|
2
|
+
if (status === "connecting") return "connecting";
|
|
3
|
+
if (status === "connected") return "connected";
|
|
4
|
+
if (status === "error") return "error";
|
|
5
|
+
return "disconnected";
|
|
6
|
+
}
|
|
7
|
+
const GatewayConnector = ({
|
|
8
|
+
tone = "default",
|
|
9
|
+
disabled = false
|
|
10
|
+
}) => {
|
|
11
|
+
const cdecli = useCdecliConnection();
|
|
12
|
+
const gatewayStatus = mapCdecliStatus(cdecli.status);
|
|
13
|
+
const gatewayLabel = cdecli.status === "connecting" ? "Checking..." : void 0;
|
|
14
|
+
const handleToggleGateway = useCallback(() => {
|
|
15
|
+
}, []);
|
|
16
|
+
return /* @__PURE__ */ jsx(GatewayToolbarButtonMobile, { gatewayStatus, gatewayError: cdecli.error, onToggleGateway: handleToggleGateway, disabled, statusLabel: gatewayLabel, tone });
|
|
17
|
+
};
|
|
18
|
+
var GatewayConnector$1 = React.memo(GatewayConnector);export{GatewayConnector$1 as default};//# sourceMappingURL=GatewayConnector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GatewayConnector.js","sources":["../../../src/components/GatewayConnector/GatewayConnector.tsx"],"sourcesContent":["/**\n * Gateway connector pill.\n *\n * Renders the visual CDeCLI status pill (`GatewayToolbarButtonMobile`) using\n * the shared `CdecliConnectionContext`. It is purely a consumer — the actual\n * `useCdecliAutoConnect` lifecycle lives in `CdecliConnectionProvider`\n * mounted once at the app root.\n *\n * This separation is intentional: the Chat screen also binds its `channelId`\n * to the same shared connection. If this component called its own\n * `useCdecliAutoConnect`, the two hooks would race their `gatewayConnect`\n * mutations and the agent session would lose its chat binding, producing the\n * \"agent did not return a response / API key may be missing\" fallback.\n */\nimport React, { useCallback } from 'react';\nimport { useCdecliConnection } from '../../contexts/CdecliConnectionContext';\nimport { GatewayToolbarButtonMobile } from '../GatewayToolbarButtonMobile';\n\nexport type GatewayConnectorStatus = 'connecting' | 'connected' | 'disconnected' | 'error';\n\ninterface GatewayConnectorProps {\n /** Visual variant — defaults to the standard toolbar tone. */\n tone?: 'default' | 'provisioning' | 'workspace-error';\n /** Disable interaction (the pill itself is currently click-through). */\n disabled?: boolean;\n}\n\nfunction mapCdecliStatus(status: string | null | undefined): GatewayConnectorStatus {\n if (status === 'connecting') return 'connecting';\n if (status === 'connected') return 'connected';\n if (status === 'error') return 'error';\n return 'disconnected';\n}\n\nconst GatewayConnector: React.FC<GatewayConnectorProps> = ({ tone = 'default', disabled = false }) => {\n const cdecli = useCdecliConnection();\n\n const gatewayStatus = mapCdecliStatus(cdecli.status);\n const gatewayLabel = cdecli.status === 'connecting' ? 'Checking...' : undefined;\n\n const handleToggleGateway = useCallback(() => {\n /* CDeCLI selection is gateway-context driven elsewhere — no-op here. */\n }, []);\n\n return (\n <GatewayToolbarButtonMobile\n gatewayStatus={gatewayStatus}\n gatewayError={cdecli.error}\n onToggleGateway={handleToggleGateway}\n disabled={disabled}\n statusLabel={gatewayLabel}\n tone={tone}\n />\n );\n};\n\nexport default React.memo(GatewayConnector);\n"],"names":[],"mappings":"gOAwBA,SAAS,gBAAgB,MAA2D,EAAA;AAClF,EAAI,IAAA,MAAA,KAAW,cAAqB,OAAA,YAAA;AACpC,EAAI,IAAA,MAAA,KAAW,aAAoB,OAAA,WAAA;AACnC,EAAI,IAAA,MAAA,KAAW,SAAgB,OAAA,OAAA;AAC/B,EAAO,OAAA,cAAA;AACT;AACA,MAAM,mBAAoD,CAAC;AAAA,EACzD,IAAO,GAAA,SAAA;AAAA,EACP,QAAW,GAAA;AACb,CAAM,KAAA;AACJ,EAAA,MAAM,SAAS,mBAAoB,EAAA;AACnC,EAAM,MAAA,aAAA,GAAgB,eAAgB,CAAA,MAAA,CAAO,MAAM,CAAA;AACnD,EAAA,MAAM,YAAe,GAAA,MAAA,CAAO,MAAW,KAAA,YAAA,GAAe,aAAgB,GAAA,MAAA;AACtE,EAAM,MAAA,mBAAA,GAAsB,YAAY,MAAM;AAAA,GAE9C,EAAG,EAAE,CAAA;AACL,EAAO,uBAAA,GAAA,CAAC,0BAA2B,EAAA,EAAA,aAAA,EAA8B,YAAc,EAAA,MAAA,CAAO,KAAO,EAAA,eAAA,EAAiB,mBAAqB,EAAA,QAAA,EAAoB,WAAa,EAAA,YAAA,EAAc,IAAY,EAAA,CAAA;AAChM,CAAA;AACA,yBAAe,KAAA,CAAM,KAAK,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {jsx,jsxs}from'react/jsx-runtime';import {View,StyleSheet,Pressable,ActivityIndicator,Text}from'react-native';import {MaterialCommunityIcons}from'@expo/vector-icons';import {mobileTokens}from'../theme/mobileTokens.js';function toneStyles(status, tone) {
|
|
2
|
+
if (tone === "provisioning") {
|
|
3
|
+
return {
|
|
4
|
+
bg: "#dbeafe",
|
|
5
|
+
border: "#93c5fd",
|
|
6
|
+
text: "#1d4ed8"
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
if (tone === "workspace-error") {
|
|
10
|
+
return {
|
|
11
|
+
bg: mobileTokens.color.dangerSoft,
|
|
12
|
+
border: "#fecaca",
|
|
13
|
+
text: mobileTokens.color.dangerText
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
if (status === "connected") return {
|
|
17
|
+
bg: mobileTokens.color.successSoft,
|
|
18
|
+
border: "#86efac",
|
|
19
|
+
text: mobileTokens.color.successText
|
|
20
|
+
};
|
|
21
|
+
if (status === "connecting") return {
|
|
22
|
+
bg: mobileTokens.color.warningSoft,
|
|
23
|
+
border: "#fde68a",
|
|
24
|
+
text: mobileTokens.color.warningText
|
|
25
|
+
};
|
|
26
|
+
if (status === "error") return {
|
|
27
|
+
bg: mobileTokens.color.dangerSoft,
|
|
28
|
+
border: "#fecaca",
|
|
29
|
+
text: mobileTokens.color.dangerText
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
bg: mobileTokens.color.surfaceMuted,
|
|
33
|
+
border: mobileTokens.color.border,
|
|
34
|
+
text: mobileTokens.color.textMuted
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function GatewayToolbarButtonMobile({
|
|
38
|
+
gatewayStatus,
|
|
39
|
+
gatewayError,
|
|
40
|
+
onToggleGateway,
|
|
41
|
+
disabled,
|
|
42
|
+
statusLabel,
|
|
43
|
+
tone = "default"
|
|
44
|
+
}) {
|
|
45
|
+
const colors = toneStyles(gatewayStatus, tone);
|
|
46
|
+
const mainTitle = gatewayStatus === "connected" ? "Disconnect gateway" : gatewayError || "Connect to workspace gateway";
|
|
47
|
+
return /* @__PURE__ */ jsx(View, { style: styles.wrap, children: /* @__PURE__ */ jsxs(Pressable, { onPress: onToggleGateway, disabled, accessibilityLabel: mainTitle, style: ({
|
|
48
|
+
pressed
|
|
49
|
+
}) => [styles.mainBtn, {
|
|
50
|
+
backgroundColor: colors.bg,
|
|
51
|
+
borderColor: colors.border
|
|
52
|
+
}, pressed && styles.pressed, disabled && styles.disabled], children: [
|
|
53
|
+
gatewayStatus === "connecting" ? /* @__PURE__ */ jsx(ActivityIndicator, { size: "small", color: colors.text }) : /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: gatewayStatus === "connected" ? "wifi" : "wifi-off", size: 18, color: colors.text }),
|
|
54
|
+
/* @__PURE__ */ jsx(Text, { style: [styles.label, {
|
|
55
|
+
color: colors.text
|
|
56
|
+
}], children: statusLabel != null ? statusLabel : "Gateway" })
|
|
57
|
+
] }) });
|
|
58
|
+
}
|
|
59
|
+
const styles = StyleSheet.create({
|
|
60
|
+
wrap: {
|
|
61
|
+
marginRight: 2
|
|
62
|
+
},
|
|
63
|
+
mainBtn: {
|
|
64
|
+
flexDirection: "row",
|
|
65
|
+
alignItems: "center",
|
|
66
|
+
gap: 5,
|
|
67
|
+
height: 34,
|
|
68
|
+
paddingHorizontal: 10,
|
|
69
|
+
borderRadius: 11,
|
|
70
|
+
borderWidth: 1,
|
|
71
|
+
minWidth: 88,
|
|
72
|
+
justifyContent: "flex-start"
|
|
73
|
+
},
|
|
74
|
+
pressed: {
|
|
75
|
+
opacity: 0.75
|
|
76
|
+
},
|
|
77
|
+
disabled: {
|
|
78
|
+
opacity: 0.45
|
|
79
|
+
},
|
|
80
|
+
label: {
|
|
81
|
+
fontSize: 12,
|
|
82
|
+
fontWeight: "700"
|
|
83
|
+
}
|
|
84
|
+
});export{GatewayToolbarButtonMobile};//# sourceMappingURL=GatewayToolbarButtonMobile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GatewayToolbarButtonMobile.js","sources":["../../src/components/GatewayToolbarButtonMobile.tsx"],"sourcesContent":["/**\n * Connect/disconnect + gateway provider picker — mirrors web\n * `GatewayToolbarButton` for React Native header usage.\n */\n\nimport React from 'react';\nimport { ActivityIndicator, Pressable, StyleSheet, Text, View } from 'react-native';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { mobileTokens } from '../theme/mobileTokens';\n\nexport type GatewayToolbarMobileStatus = 'connected' | 'connecting' | 'disconnected' | 'error';\n\nexport interface GatewayToolbarButtonMobileProps {\n gatewayStatus: GatewayToolbarMobileStatus;\n gatewayError?: string | null;\n onToggleGateway: () => void;\n disabled?: boolean;\n /** Replaces the \"Gateway\" label, e.g. \"Setting up...\" */\n statusLabel?: string;\n /** Visual override when workspace (not link status) is provisioning / error */\n tone?: 'default' | 'provisioning' | 'workspace-error';\n}\n\nfunction toneStyles(status: GatewayToolbarMobileStatus, tone: GatewayToolbarButtonMobileProps['tone']) {\n if (tone === 'provisioning') {\n return { bg: '#dbeafe', border: '#93c5fd', text: '#1d4ed8' };\n }\n if (tone === 'workspace-error') {\n return { bg: mobileTokens.color.dangerSoft, border: '#fecaca', text: mobileTokens.color.dangerText };\n }\n if (status === 'connected')\n return { bg: mobileTokens.color.successSoft, border: '#86efac', text: mobileTokens.color.successText };\n if (status === 'connecting')\n return { bg: mobileTokens.color.warningSoft, border: '#fde68a', text: mobileTokens.color.warningText };\n if (status === 'error')\n return { bg: mobileTokens.color.dangerSoft, border: '#fecaca', text: mobileTokens.color.dangerText };\n return {\n bg: mobileTokens.color.surfaceMuted,\n border: mobileTokens.color.border,\n text: mobileTokens.color.textMuted,\n };\n}\n\nexport function GatewayToolbarButtonMobile({\n gatewayStatus,\n gatewayError,\n onToggleGateway,\n disabled,\n statusLabel,\n tone = 'default',\n}: GatewayToolbarButtonMobileProps) {\n const colors = toneStyles(gatewayStatus, tone);\n\n const mainTitle =\n gatewayStatus === 'connected' ? 'Disconnect gateway' : gatewayError || 'Connect to workspace gateway';\n\n return (\n <View style={styles.wrap}>\n <Pressable\n onPress={onToggleGateway}\n disabled={disabled}\n accessibilityLabel={mainTitle}\n style={({ pressed }) => [\n styles.mainBtn,\n { backgroundColor: colors.bg, borderColor: colors.border },\n pressed && styles.pressed,\n disabled && styles.disabled,\n ]}\n >\n {gatewayStatus === 'connecting' ? (\n <ActivityIndicator size=\"small\" color={colors.text} />\n ) : (\n <MaterialCommunityIcons\n name={gatewayStatus === 'connected' ? 'wifi' : 'wifi-off'}\n size={18}\n color={colors.text}\n />\n )}\n <Text style={[styles.label, { color: colors.text }]}>{statusLabel ?? 'Gateway'}</Text>\n </Pressable>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n wrap: { marginRight: 2 },\n mainBtn: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 5,\n height: 34,\n paddingHorizontal: 10,\n borderRadius: 11,\n borderWidth: 1,\n minWidth: 88,\n justifyContent: 'flex-start',\n },\n pressed: { opacity: 0.75 },\n disabled: { opacity: 0.45 },\n label: { fontSize: 12, fontWeight: '700' },\n});\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import {jsx,jsxs,Fragment}from'react/jsx-runtime';import React,{useMemo,useCallback}from'react';import {useColorScheme,StyleSheet,View,Pressable}from'react-native';import {useSafeAreaInsets,SafeAreaView}from'react-native-safe-area-context';import {StatusBar}from'expo-status-bar';import {useNavigation,CommonActions,DrawerActions}from'@react-navigation/native';import {getHeaderTitle}from'@react-navigation/elements';import {MaterialCommunityIcons}from'@expo/vector-icons';import {Text}from'@admin-layout/gluestack-ui-mobile';import GatewayConnector from'../GatewayConnector/GatewayConnector.js';import {mobileTokens}from'../../theme/mobileTokens.js';const ICON_SIZE = 22;
|
|
2
|
+
function resolveTitle(options, route) {
|
|
3
|
+
var _a, _b;
|
|
4
|
+
if (typeof (options == null ? void 0 : options.title) === "string" && options.title.trim()) {
|
|
5
|
+
return options.title.trim();
|
|
6
|
+
}
|
|
7
|
+
if (typeof (options == null ? void 0 : options.headerTitle) === "string" && options.headerTitle.trim()) {
|
|
8
|
+
return options.headerTitle.trim();
|
|
9
|
+
}
|
|
10
|
+
const fallback = (_b = getHeaderTitle) == null ? void 0 : _b(options != null ? options : {}, (_a = route == null ? void 0 : route.name) != null ? _a : "Yantra");
|
|
11
|
+
return typeof fallback === "string" && fallback.trim() ? fallback : "Yantra";
|
|
12
|
+
}
|
|
13
|
+
const NavigationHeader = (props) => {
|
|
14
|
+
var _a, _b, _c;
|
|
15
|
+
const {
|
|
16
|
+
navigation: navProp,
|
|
17
|
+
route,
|
|
18
|
+
options,
|
|
19
|
+
back,
|
|
20
|
+
showTitle = true,
|
|
21
|
+
showToggle = false,
|
|
22
|
+
showBack = false,
|
|
23
|
+
showGateway = false,
|
|
24
|
+
showHistory = false,
|
|
25
|
+
showNewChat = false,
|
|
26
|
+
headerBgColor
|
|
27
|
+
} = props;
|
|
28
|
+
const fallbackNav = useNavigation();
|
|
29
|
+
const navigation = navProp != null ? navProp : fallbackNav;
|
|
30
|
+
const colorScheme = useColorScheme();
|
|
31
|
+
const isDark = colorScheme === "dark";
|
|
32
|
+
const insets = useSafeAreaInsets();
|
|
33
|
+
const themeTitleColor = isDark ? "#f1f5f9" : "#0f172a";
|
|
34
|
+
const themeAccentColor = isDark ? "#a5b4fc" : "#4338ca";
|
|
35
|
+
const themeNewChatIconColor = isDark ? "#e5e7eb" : "#000000";
|
|
36
|
+
const optionTint = typeof (options == null ? void 0 : options.headerTintColor) === "string" ? options.headerTintColor : null;
|
|
37
|
+
const tintLooksDark = optionTint && /^(#?000(000)?|black)$/i.test(optionTint.trim());
|
|
38
|
+
const effectiveTint = optionTint && !(isDark && tintLooksDark) ? optionTint : null;
|
|
39
|
+
const titleColor = effectiveTint != null ? effectiveTint : themeTitleColor;
|
|
40
|
+
const iconColor = effectiveTint != null ? effectiveTint : themeTitleColor;
|
|
41
|
+
const accentColor = effectiveTint != null ? effectiveTint : themeAccentColor;
|
|
42
|
+
const newChatIconColor = effectiveTint != null ? effectiveTint : themeNewChatIconColor;
|
|
43
|
+
const surfaceColor = headerBgColor != null ? headerBgColor : isDark ? "#0f172a" : "#ffffff";
|
|
44
|
+
const dividerColor = isDark ? "rgba(148, 163, 184, 0.18)" : "rgba(15, 23, 42, 0.06)";
|
|
45
|
+
const titleAlignLeft = (options == null ? void 0 : options.headerTitleAlign) === "left";
|
|
46
|
+
const title = useMemo(() => resolveTitle(options, route), [options, route]);
|
|
47
|
+
const optionTitleStyle = (_a = options == null ? void 0 : options.headerTitleStyle) != null ? _a : null;
|
|
48
|
+
const orgName = useMemo(() => {
|
|
49
|
+
var _a2, _b2;
|
|
50
|
+
const raw = (_b2 = (_a2 = route == null ? void 0 : route.params) == null ? void 0 : _a2.orgName) != null ? _b2 : "";
|
|
51
|
+
return typeof raw === "string" && raw.trim() ? raw.trim() : null;
|
|
52
|
+
}, [(_b = route == null ? void 0 : route.params) == null ? void 0 : _b.orgName]);
|
|
53
|
+
const handleBack = useCallback(() => {
|
|
54
|
+
var _a2, _b2;
|
|
55
|
+
if ((_a2 = navigation == null ? void 0 : navigation.canGoBack) == null ? void 0 : _a2.call(navigation)) {
|
|
56
|
+
navigation.goBack();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
(_b2 = navigation == null ? void 0 : navigation.dispatch) == null ? void 0 : _b2.call(navigation, CommonActions.navigate({
|
|
60
|
+
name: "MainStack.Layout.Home",
|
|
61
|
+
params: orgName ? {
|
|
62
|
+
orgName
|
|
63
|
+
} : void 0
|
|
64
|
+
}));
|
|
65
|
+
}, [navigation, orgName]);
|
|
66
|
+
const handleToggleDrawer = useCallback(() => {
|
|
67
|
+
var _a2;
|
|
68
|
+
try {
|
|
69
|
+
(_a2 = navigation == null ? void 0 : navigation.dispatch) == null ? void 0 : _a2.call(navigation, DrawerActions.openDrawer());
|
|
70
|
+
} catch (e) {
|
|
71
|
+
}
|
|
72
|
+
}, [navigation]);
|
|
73
|
+
const handleOpenChatHistory = useCallback(() => {
|
|
74
|
+
var _a2;
|
|
75
|
+
(_a2 = navigation == null ? void 0 : navigation.dispatch) == null ? void 0 : _a2.call(navigation, CommonActions.navigate({
|
|
76
|
+
name: "MainStack.ChatHistory",
|
|
77
|
+
params: orgName ? {
|
|
78
|
+
orgName
|
|
79
|
+
} : void 0
|
|
80
|
+
}));
|
|
81
|
+
}, [navigation, orgName]);
|
|
82
|
+
const handleNewChat = useCallback(() => {
|
|
83
|
+
var _a2;
|
|
84
|
+
(_a2 = navigation == null ? void 0 : navigation.dispatch) == null ? void 0 : _a2.call(navigation, CommonActions.navigate({
|
|
85
|
+
name: "MainStack.Layout.Home",
|
|
86
|
+
params: orgName ? {
|
|
87
|
+
orgName
|
|
88
|
+
} : void 0,
|
|
89
|
+
merge: true
|
|
90
|
+
}));
|
|
91
|
+
}, [navigation, orgName]);
|
|
92
|
+
const wantsBack = Boolean(back) || showBack;
|
|
93
|
+
const leftSlot = wantsBack ? /* @__PURE__ */ jsx(Pressable, { onPress: handleBack, accessibilityLabel: "Go back", accessibilityRole: "button", style: ({
|
|
94
|
+
pressed
|
|
95
|
+
}) => [styles.iconButton, pressed && styles.iconButtonPressed], hitSlop: 8, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chevron-left", size: ICON_SIZE + 4, color: iconColor }) }) : showToggle ? /* @__PURE__ */ jsx(Pressable, { onPress: handleToggleDrawer, accessibilityLabel: "Open menu", accessibilityRole: "button", style: ({
|
|
96
|
+
pressed
|
|
97
|
+
}) => [styles.iconButton, pressed && styles.iconButtonPressed], hitSlop: 8, children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "menu", size: ICON_SIZE, color: iconColor }) }) : null;
|
|
98
|
+
const titleSlot = showTitle ? /* @__PURE__ */ jsx(Text, { style: [styles.title, titleAlignLeft ? styles.titleAlignLeft : styles.titleAlignCenter, {
|
|
99
|
+
color: titleColor
|
|
100
|
+
}, optionTitleStyle], numberOfLines: 1, ellipsizeMode: "tail", children: title }) : null;
|
|
101
|
+
const showRightSlot = showGateway || showHistory || showNewChat;
|
|
102
|
+
const rightSlot = showRightSlot ? /* @__PURE__ */ jsxs(View, { style: styles.rightActions, children: [
|
|
103
|
+
showGateway ? /* @__PURE__ */ jsx(GatewayConnector, {}) : null,
|
|
104
|
+
showHistory ? /* @__PURE__ */ jsx(Pressable, { onPress: handleOpenChatHistory, style: ({
|
|
105
|
+
pressed
|
|
106
|
+
}) => [styles.actionButton, pressed && styles.actionButtonPressed], accessibilityLabel: "Chat history", accessibilityRole: "button", hitSlop: 8, children: /* @__PURE__ */ jsx(View, { style: [styles.actionButtonInner, isDark ? styles.actionButtonInnerDark : null], children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "history", size: 19, color: accentColor }) }) }) : null,
|
|
107
|
+
showNewChat ? /* @__PURE__ */ jsx(Pressable, { onPress: handleNewChat, style: ({
|
|
108
|
+
pressed
|
|
109
|
+
}) => [styles.actionButton, pressed && styles.actionButtonPressed], accessibilityLabel: "New chat", accessibilityRole: "button", hitSlop: 8, children: /* @__PURE__ */ jsx(View, { style: [styles.actionButtonInner, isDark ? styles.actionButtonInnerDark : null], children: /* @__PURE__ */ jsx(MaterialCommunityIcons, { name: "chat-plus-outline", size: 20, color: newChatIconColor }) }) }) : null
|
|
110
|
+
] }) : null;
|
|
111
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
112
|
+
/* @__PURE__ */ jsx(StatusBar, { style: isDark ? "light" : "dark" }),
|
|
113
|
+
/* @__PURE__ */ jsx(SafeAreaView, { edges: ["top"], style: {
|
|
114
|
+
backgroundColor: surfaceColor
|
|
115
|
+
}, children: /* @__PURE__ */ jsxs(View, { style: [styles.row, {
|
|
116
|
+
backgroundColor: surfaceColor,
|
|
117
|
+
borderBottomColor: dividerColor,
|
|
118
|
+
paddingTop: insets.top > 0 ? 0 : 6
|
|
119
|
+
}, (_c = options == null ? void 0 : options.headerStyle) != null ? _c : null], children: [
|
|
120
|
+
/* @__PURE__ */ jsx(View, { style: styles.leftSlot, children: leftSlot }),
|
|
121
|
+
/* @__PURE__ */ jsx(View, { style: [styles.titleSlot, titleAlignLeft && styles.titleSlotLeft], children: titleSlot }),
|
|
122
|
+
/* @__PURE__ */ jsx(View, { style: styles.rightSlot, children: rightSlot })
|
|
123
|
+
] }) })
|
|
124
|
+
] });
|
|
125
|
+
};
|
|
126
|
+
const styles = StyleSheet.create({
|
|
127
|
+
row: {
|
|
128
|
+
flexDirection: "row",
|
|
129
|
+
alignItems: "center",
|
|
130
|
+
paddingHorizontal: 12,
|
|
131
|
+
paddingVertical: 10,
|
|
132
|
+
minHeight: 52,
|
|
133
|
+
borderBottomWidth: StyleSheet.hairlineWidth
|
|
134
|
+
},
|
|
135
|
+
leftSlot: {
|
|
136
|
+
minWidth: 40,
|
|
137
|
+
alignItems: "flex-start",
|
|
138
|
+
justifyContent: "center"
|
|
139
|
+
},
|
|
140
|
+
titleSlot: {
|
|
141
|
+
flex: 1,
|
|
142
|
+
alignItems: "center",
|
|
143
|
+
justifyContent: "center",
|
|
144
|
+
paddingHorizontal: 8,
|
|
145
|
+
minWidth: 0
|
|
146
|
+
},
|
|
147
|
+
titleSlotLeft: {
|
|
148
|
+
alignItems: "flex-start"
|
|
149
|
+
},
|
|
150
|
+
rightSlot: {
|
|
151
|
+
minWidth: 40,
|
|
152
|
+
alignItems: "flex-end",
|
|
153
|
+
justifyContent: "center"
|
|
154
|
+
},
|
|
155
|
+
rightActions: {
|
|
156
|
+
flexDirection: "row",
|
|
157
|
+
alignItems: "center",
|
|
158
|
+
gap: 6
|
|
159
|
+
},
|
|
160
|
+
title: {
|
|
161
|
+
fontSize: 17,
|
|
162
|
+
fontWeight: "700",
|
|
163
|
+
letterSpacing: -0.2,
|
|
164
|
+
width: "100%"
|
|
165
|
+
},
|
|
166
|
+
titleAlignCenter: {
|
|
167
|
+
textAlign: "center"
|
|
168
|
+
},
|
|
169
|
+
titleAlignLeft: {
|
|
170
|
+
textAlign: "left"
|
|
171
|
+
},
|
|
172
|
+
iconButton: {
|
|
173
|
+
width: 36,
|
|
174
|
+
height: 36,
|
|
175
|
+
alignItems: "center",
|
|
176
|
+
justifyContent: "center",
|
|
177
|
+
borderRadius: 18
|
|
178
|
+
},
|
|
179
|
+
iconButtonPressed: {
|
|
180
|
+
opacity: 0.6
|
|
181
|
+
},
|
|
182
|
+
actionButton: {
|
|
183
|
+
padding: 0,
|
|
184
|
+
alignItems: "center",
|
|
185
|
+
justifyContent: "center",
|
|
186
|
+
borderRadius: 22
|
|
187
|
+
},
|
|
188
|
+
actionButtonPressed: {
|
|
189
|
+
opacity: 0.6
|
|
190
|
+
},
|
|
191
|
+
actionButtonInner: {
|
|
192
|
+
width: 32,
|
|
193
|
+
height: 32,
|
|
194
|
+
borderRadius: 16,
|
|
195
|
+
alignItems: "center",
|
|
196
|
+
justifyContent: "center",
|
|
197
|
+
backgroundColor: mobileTokens.color.surface,
|
|
198
|
+
borderWidth: 1,
|
|
199
|
+
borderColor: mobileTokens.color.border,
|
|
200
|
+
shadowColor: "#0f172a",
|
|
201
|
+
shadowOpacity: 0.08,
|
|
202
|
+
shadowRadius: 5,
|
|
203
|
+
shadowOffset: {
|
|
204
|
+
width: 0,
|
|
205
|
+
height: 2
|
|
206
|
+
},
|
|
207
|
+
elevation: 2
|
|
208
|
+
},
|
|
209
|
+
actionButtonInnerDark: {
|
|
210
|
+
backgroundColor: "#0f172a",
|
|
211
|
+
borderColor: "#334155"
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
var NavigationHeader$1 = React.memo(NavigationHeader);export{NavigationHeader$1 as default};//# sourceMappingURL=NavigationHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NavigationHeader.js","sources":["../../../src/components/NavigationHeader/NavigationHeader.tsx"],"sourcesContent":["/**\n * Universal navigation header for the Yantra mobile app.\n *\n * Wired via `customHeader` in `compute.ts`, so the React Navigation runtime\n * passes us TWO sets of props on every render:\n *\n * 1. The standard navigator props — `navigation`, `route`, `options`, `back`,\n * `layout`. We read EVERYTHING visual out of `options` (set by `props.options`\n * in compute.ts):\n * • `options.title` / `options.headerTitle` — visible title text\n * • `options.headerTitleAlign` — `'left' | 'center'`\n * • `options.headerTitleStyle` — text style overrides (fontWeight, etc.)\n * • `options.headerTintColor` — title + icon tint (light-mode default)\n * • `options.headerStyle` — outer header view style overrides\n *\n * 2. The static `customHeader.props` from compute.ts — the layout flags\n * describing what the header should render for this route:\n * • `showTitle, showToggle, showBack, showFilter, isSearchBack`\n * • `showGateway, showHistory, showNewChat` (`showGateway` is intended for Home only)\n * • `headerBgColor`\n *\n * Screens never touch the header — no `setOptions`, no slot registration.\n * If a route needs a different header configuration, change its\n * `customHeader.props` / `props.options` in `compute.ts`.\n */\nimport React, { useCallback, useMemo } from 'react';\nimport { Pressable, StyleSheet, View, useColorScheme } from 'react-native';\nimport { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';\nimport { StatusBar } from 'expo-status-bar';\nimport { CommonActions, DrawerActions, useNavigation } from '@react-navigation/native';\nimport { getHeaderTitle } from '@react-navigation/elements';\nimport { MaterialCommunityIcons } from '@expo/vector-icons';\nimport { Text } from '@admin-layout/gluestack-ui-mobile';\nimport { GatewayConnector } from '../GatewayConnector';\nimport { mobileTokens } from '../../theme/mobileTokens';\n\ninterface NavigationHeaderProps {\n /** React Navigation header props (typed loose because they vary per navigator). */\n navigation?: any;\n route?: any;\n options?: any;\n /** Set by the native-stack navigator when there's a previous screen on the stack. */\n back?: { title?: string };\n\n showTitle?: boolean;\n showToggle?: boolean;\n showBack?: boolean;\n showFilter?: boolean;\n isSearchBack?: boolean;\n showGateway?: boolean;\n showHistory?: boolean;\n showNewChat?: boolean;\n headerBgColor?: string;\n}\n\nconst ICON_SIZE = 22;\n\nfunction resolveTitle(options: any, route: any): string {\n if (typeof options?.title === 'string' && options.title.trim()) {\n return options.title.trim();\n }\n if (typeof options?.headerTitle === 'string' && options.headerTitle.trim()) {\n return options.headerTitle.trim();\n }\n const fallback = getHeaderTitle?.(options ?? {}, route?.name ?? 'Yantra');\n return typeof fallback === 'string' && fallback.trim() ? fallback : 'Yantra';\n}\n\nconst NavigationHeader: React.FC<NavigationHeaderProps> = (props) => {\n const {\n navigation: navProp,\n route,\n options,\n back,\n showTitle = true,\n showToggle = false,\n showBack = false,\n showGateway = false,\n showHistory = false,\n showNewChat = false,\n headerBgColor,\n } = props;\n\n const fallbackNav = useNavigation<any>();\n const navigation = navProp ?? fallbackNav;\n\n const colorScheme = useColorScheme();\n const isDark = colorScheme === 'dark';\n const insets = useSafeAreaInsets();\n\n /* ── Theme + options-driven colours / styles ─────────────────────────── */\n const themeTitleColor = isDark ? '#f1f5f9' : '#0f172a';\n const themeAccentColor = isDark ? '#a5b4fc' : '#4338ca';\n const themeNewChatIconColor = isDark ? '#e5e7eb' : '#000000';\n\n /**\n * Honour `options.headerTintColor` (set in `compute.ts` → `props.options`).\n * In dark mode we ignore a hard \"black\" tint so the title stays legible —\n * but any non-black tint is respected in both modes.\n */\n const optionTint = typeof options?.headerTintColor === 'string' ? options.headerTintColor : null;\n const tintLooksDark = optionTint && /^(#?000(000)?|black)$/i.test(optionTint.trim());\n const effectiveTint = optionTint && !(isDark && tintLooksDark) ? optionTint : null;\n\n const titleColor = effectiveTint ?? themeTitleColor;\n const iconColor = effectiveTint ?? themeTitleColor;\n const accentColor = effectiveTint ?? themeAccentColor;\n const newChatIconColor = effectiveTint ?? themeNewChatIconColor;\n\n const surfaceColor = headerBgColor ?? (isDark ? '#0f172a' : '#ffffff');\n const dividerColor = isDark ? 'rgba(148, 163, 184, 0.18)' : 'rgba(15, 23, 42, 0.06)';\n\n const titleAlignLeft = options?.headerTitleAlign === 'left';\n const title = useMemo(() => resolveTitle(options, route), [options, route]);\n const optionTitleStyle = options?.headerTitleStyle ?? null;\n\n /** Org slug used by header navigation actions; falls back to route params. */\n const orgName = useMemo(() => {\n const raw = (route?.params?.orgName as string | undefined) ?? '';\n return typeof raw === 'string' && raw.trim() ? raw.trim() : null;\n }, [route?.params?.orgName]);\n\n /* ── Action handlers ─────────────────────────────────────────────────── */\n const handleBack = useCallback(() => {\n if (navigation?.canGoBack?.()) {\n navigation.goBack();\n return;\n }\n navigation?.dispatch?.(\n CommonActions.navigate({\n name: 'MainStack.Layout.Home',\n params: orgName ? { orgName } : undefined,\n }),\n );\n }, [navigation, orgName]);\n\n const handleToggleDrawer = useCallback(() => {\n try {\n navigation?.dispatch?.(DrawerActions.openDrawer());\n } catch {\n /* Current navigator may not be a drawer — ignore. */\n }\n }, [navigation]);\n\n const handleOpenChatHistory = useCallback(() => {\n navigation?.dispatch?.(\n CommonActions.navigate({\n name: 'MainStack.ChatHistory',\n params: orgName ? { orgName } : undefined,\n }),\n );\n }, [navigation, orgName]);\n\n const handleNewChat = useCallback(() => {\n navigation?.dispatch?.(\n CommonActions.navigate({\n name: 'MainStack.Layout.Home',\n params: orgName ? { orgName } : undefined,\n merge: true,\n }),\n );\n }, [navigation, orgName]);\n\n /* ── Slot composition (left → title → right) ─────────────────────────── */\n const wantsBack = Boolean(back) || showBack;\n\n const leftSlot = wantsBack ? (\n <Pressable\n onPress={handleBack}\n accessibilityLabel=\"Go back\"\n accessibilityRole=\"button\"\n style={({ pressed }) => [styles.iconButton, pressed && styles.iconButtonPressed]}\n hitSlop={8}\n >\n <MaterialCommunityIcons name=\"chevron-left\" size={ICON_SIZE + 4} color={iconColor} />\n </Pressable>\n ) : showToggle ? (\n <Pressable\n onPress={handleToggleDrawer}\n accessibilityLabel=\"Open menu\"\n accessibilityRole=\"button\"\n style={({ pressed }) => [styles.iconButton, pressed && styles.iconButtonPressed]}\n hitSlop={8}\n >\n <MaterialCommunityIcons name=\"menu\" size={ICON_SIZE} color={iconColor} />\n </Pressable>\n ) : null;\n\n const titleSlot = showTitle ? (\n <Text\n style={[\n styles.title,\n titleAlignLeft ? styles.titleAlignLeft : styles.titleAlignCenter,\n { color: titleColor },\n optionTitleStyle,\n ]}\n numberOfLines={1}\n ellipsizeMode=\"tail\"\n >\n {title}\n </Text>\n ) : null;\n\n const showRightSlot = showGateway || showHistory || showNewChat;\n const rightSlot = showRightSlot ? (\n <View style={styles.rightActions}>\n {showGateway ? <GatewayConnector /> : null}\n {showHistory ? (\n <Pressable\n onPress={handleOpenChatHistory}\n style={({ pressed }) => [styles.actionButton, pressed && styles.actionButtonPressed]}\n accessibilityLabel=\"Chat history\"\n accessibilityRole=\"button\"\n hitSlop={8}\n >\n <View style={[styles.actionButtonInner, isDark ? styles.actionButtonInnerDark : null]}>\n <MaterialCommunityIcons name=\"history\" size={19} color={accentColor} />\n </View>\n </Pressable>\n ) : null}\n {showNewChat ? (\n <Pressable\n onPress={handleNewChat}\n style={({ pressed }) => [styles.actionButton, pressed && styles.actionButtonPressed]}\n accessibilityLabel=\"New chat\"\n accessibilityRole=\"button\"\n hitSlop={8}\n >\n <View style={[styles.actionButtonInner, isDark ? styles.actionButtonInnerDark : null]}>\n <MaterialCommunityIcons name=\"chat-plus-outline\" size={20} color={newChatIconColor} />\n </View>\n </Pressable>\n ) : null}\n </View>\n ) : null;\n\n return (\n <>\n <StatusBar style={isDark ? 'light' : 'dark'} />\n <SafeAreaView edges={['top']} style={{ backgroundColor: surfaceColor }}>\n <View\n style={[\n styles.row,\n {\n backgroundColor: surfaceColor,\n borderBottomColor: dividerColor,\n paddingTop: insets.top > 0 ? 0 : 6,\n },\n options?.headerStyle ?? null,\n ]}\n >\n <View style={styles.leftSlot}>{leftSlot}</View>\n <View style={[styles.titleSlot, titleAlignLeft && styles.titleSlotLeft]}>{titleSlot}</View>\n <View style={styles.rightSlot}>{rightSlot}</View>\n </View>\n </SafeAreaView>\n </>\n );\n};\n\nconst styles = StyleSheet.create({\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingHorizontal: 12,\n paddingVertical: 10,\n minHeight: 52,\n borderBottomWidth: StyleSheet.hairlineWidth,\n },\n leftSlot: {\n minWidth: 40,\n alignItems: 'flex-start',\n justifyContent: 'center',\n },\n titleSlot: {\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: 8,\n minWidth: 0,\n },\n titleSlotLeft: {\n alignItems: 'flex-start',\n },\n rightSlot: {\n minWidth: 40,\n alignItems: 'flex-end',\n justifyContent: 'center',\n },\n rightActions: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 6,\n },\n title: {\n fontSize: 17,\n fontWeight: '700',\n letterSpacing: -0.2,\n width: '100%',\n },\n titleAlignCenter: {\n textAlign: 'center',\n },\n titleAlignLeft: {\n textAlign: 'left',\n },\n iconButton: {\n width: 36,\n height: 36,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 18,\n },\n iconButtonPressed: {\n opacity: 0.6,\n },\n actionButton: {\n padding: 0,\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: 22,\n },\n actionButtonPressed: {\n opacity: 0.6,\n },\n actionButtonInner: {\n width: 32,\n height: 32,\n borderRadius: 16,\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: mobileTokens.color.surface,\n borderWidth: 1,\n borderColor: mobileTokens.color.border,\n shadowColor: '#0f172a',\n shadowOpacity: 0.08,\n shadowRadius: 5,\n shadowOffset: { width: 0, height: 2 },\n elevation: 2,\n },\n actionButtonInnerDark: {\n backgroundColor: '#0f172a',\n borderColor: '#334155',\n },\n});\n\nexport default React.memo(NavigationHeader);\n"],"names":["_a","_b"],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {jsxs,jsx}from'react/jsx-runtime';import {useRef,useEffect}from'react';import {Animated,Easing,View,StyleSheet}from'react-native';import {Text}from'@admin-layout/gluestack-ui-mobile';function ThinkingIndicator({
|
|
2
|
+
color,
|
|
3
|
+
label = "Thinking\u2026"
|
|
4
|
+
}) {
|
|
5
|
+
const rotation = useRef(new Animated.Value(0)).current;
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const loop = Animated.loop(Animated.timing(rotation, {
|
|
8
|
+
toValue: 1,
|
|
9
|
+
duration: 900,
|
|
10
|
+
easing: Easing.linear,
|
|
11
|
+
useNativeDriver: true
|
|
12
|
+
}));
|
|
13
|
+
loop.start();
|
|
14
|
+
return () => loop.stop();
|
|
15
|
+
}, [rotation]);
|
|
16
|
+
const rotate = rotation.interpolate({
|
|
17
|
+
inputRange: [0, 1],
|
|
18
|
+
outputRange: ["0deg", "360deg"]
|
|
19
|
+
});
|
|
20
|
+
return /* @__PURE__ */ jsxs(View, { style: styles.row, children: [
|
|
21
|
+
/* @__PURE__ */ jsx(Animated.View, { style: [styles.spinner, label ? styles.spinnerWithLabel : null, {
|
|
22
|
+
borderTopColor: color,
|
|
23
|
+
borderRightColor: color,
|
|
24
|
+
borderBottomColor: color,
|
|
25
|
+
transform: [{
|
|
26
|
+
rotate
|
|
27
|
+
}]
|
|
28
|
+
}] }),
|
|
29
|
+
label ? /* @__PURE__ */ jsx(Text, { style: [styles.label, {
|
|
30
|
+
color
|
|
31
|
+
}], children: label }) : null
|
|
32
|
+
] });
|
|
33
|
+
}
|
|
34
|
+
const styles = StyleSheet.create({
|
|
35
|
+
row: {
|
|
36
|
+
flexDirection: "row",
|
|
37
|
+
alignItems: "center"
|
|
38
|
+
},
|
|
39
|
+
spinner: {
|
|
40
|
+
width: 14,
|
|
41
|
+
height: 14,
|
|
42
|
+
borderRadius: 7,
|
|
43
|
+
borderWidth: 1.5,
|
|
44
|
+
borderLeftColor: "transparent"
|
|
45
|
+
},
|
|
46
|
+
spinnerWithLabel: {
|
|
47
|
+
marginRight: 8
|
|
48
|
+
},
|
|
49
|
+
label: {
|
|
50
|
+
fontSize: 12,
|
|
51
|
+
fontWeight: "500",
|
|
52
|
+
letterSpacing: 0.2,
|
|
53
|
+
opacity: 0.9
|
|
54
|
+
}
|
|
55
|
+
});export{ThinkingIndicator as default};//# sourceMappingURL=ThinkingIndicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThinkingIndicator.js","sources":["../../src/components/ThinkingIndicator.tsx"],"sourcesContent":["import React, { useEffect, useRef } from 'react';\nimport { Animated, Easing, StyleSheet, View } from 'react-native';\nimport { Text } from '@admin-layout/gluestack-ui-mobile';\n\ninterface ThinkingIndicatorProps {\n /** Foreground tint for both the spinner ring and the caption. */\n color: string;\n /**\n * Optional caption. Defaults to `Thinking…` to mirror the web composer's\n * status pill (`packages-modules/account/browser/src/pages/chat/ChatSessionPage.tsx`).\n * Pass an empty string to render only the spinner ring.\n */\n label?: string;\n}\n\n/**\n * Shared \"thinking\" status row used by Chat and Chat History.\n *\n * Visual parity with the web composer (`ChatSessionPage.tsx`):\n * • Thin circular outline arc (mirrors lucide's `Loader2`) — drawn with a\n * 1.5px border and one transparent side so the spin reads as a single\n * curved stroke, not the iOS dotted-wheel that RN's `ActivityIndicator`\n * produces.\n * • 12px muted caption to the right of the spinner, matching web's\n * `text-xs text-muted-foreground`.\n *\n * The animation lifecycle is owned by this component so the `Animated.loop`\n * only runs while the indicator is mounted (i.e. only while the consumer is\n * actually waiting on something). On unmount we stop the loop to release\n * the driver tick.\n */\nexport default function ThinkingIndicator({ color, label = 'Thinking…' }: ThinkingIndicatorProps) {\n const rotation = useRef(new Animated.Value(0)).current;\n useEffect(() => {\n const loop = Animated.loop(\n Animated.timing(rotation, {\n toValue: 1,\n duration: 900,\n easing: Easing.linear,\n useNativeDriver: true,\n }),\n );\n loop.start();\n return () => loop.stop();\n }, [rotation]);\n const rotate = rotation.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] });\n return (\n <View style={styles.row}>\n <Animated.View\n style={[\n styles.spinner,\n label ? styles.spinnerWithLabel : null,\n {\n borderTopColor: color,\n borderRightColor: color,\n borderBottomColor: color,\n transform: [{ rotate }],\n },\n ]}\n />\n {label ? <Text style={[styles.label, { color }]}>{label}</Text> : null}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n },\n spinner: {\n width: 14,\n height: 14,\n borderRadius: 7,\n borderWidth: 1.5,\n borderLeftColor: 'transparent',\n },\n spinnerWithLabel: {\n marginRight: 8,\n },\n label: {\n fontSize: 12,\n fontWeight: '500',\n letterSpacing: 0.2,\n opacity: 0.9,\n },\n});\n"],"names":[],"mappings":"8LA8BA,SAAwB,iBAAkB,CAAA;AAAA,EACxC,KAAA;AAAA,EACA,KAAQ,GAAA;AACV,CAA2B,EAAA;AACzB,EAAA,MAAM,WAAW,MAAO,CAAA,IAAI,SAAS,KAAM,CAAA,CAAC,CAAC,CAAE,CAAA,OAAA;AAC/C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,IAAO,GAAA,QAAA,CAAS,IAAK,CAAA,QAAA,CAAS,OAAO,QAAU,EAAA;AAAA,MACnD,OAAS,EAAA,CAAA;AAAA,MACT,QAAU,EAAA,GAAA;AAAA,MACV,QAAQ,MAAO,CAAA,MAAA;AAAA,MACf,eAAiB,EAAA;AAAA,KAClB,CAAC,CAAA;AACF,IAAA,IAAA,CAAK,KAAM,EAAA;AACX,IAAO,OAAA,MAAM,KAAK,IAAK,EAAA;AAAA,GACzB,EAAG,CAAC,QAAQ,CAAC,CAAA;AACb,EAAM,MAAA,MAAA,GAAS,SAAS,WAAY,CAAA;AAAA,IAClC,UAAA,EAAY,CAAC,CAAA,EAAG,CAAC,CAAA;AAAA,IACjB,WAAA,EAAa,CAAC,MAAA,EAAQ,QAAQ;AAAA,GAC/B,CAAA;AACD,EAAA,uBAAQ,IAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,MAAA,CAAO,GACjB,EAAA,QAAA,EAAA;AAAA,oBAAC,GAAA,CAAA,QAAA,CAAS,IAAT,EAAA,EAAc,KAAO,EAAA,CAAC,OAAO,OAAS,EAAA,KAAA,GAAQ,MAAO,CAAA,gBAAA,GAAmB,IAAM,EAAA;AAAA,MACrF,cAAgB,EAAA,KAAA;AAAA,MAChB,gBAAkB,EAAA,KAAA;AAAA,MAClB,iBAAmB,EAAA,KAAA;AAAA,MACnB,WAAW,CAAC;AAAA,QACV;AAAA,OACD;AAAA,KACF,CAAG,EAAA,CAAA;AAAA,IACK,wBAAS,GAAA,CAAA,IAAA,EAAA,EAAK,KAAO,EAAA,CAAC,OAAO,KAAO,EAAA;AAAA,MAC3C;AAAA,KACD,CAAI,EAAA,QAAA,EAAA,KAAA,EAAM,CAAU,GAAA;AAAA,GACjB,EAAA,CAAA;AACR;AACA,MAAM,MAAA,GAAS,WAAW,MAAO,CAAA;AAAA,EAC/B,GAAK,EAAA;AAAA,IACH,aAAe,EAAA,KAAA;AAAA,IACf,UAAY,EAAA;AAAA,GACd;AAAA,EACA,OAAS,EAAA;AAAA,IACP,KAAO,EAAA,EAAA;AAAA,IACP,MAAQ,EAAA,EAAA;AAAA,IACR,YAAc,EAAA,CAAA;AAAA,IACd,WAAa,EAAA,GAAA;AAAA,IACb,eAAiB,EAAA;AAAA,GACnB;AAAA,EACA,gBAAkB,EAAA;AAAA,IAChB,WAAa,EAAA;AAAA,GACf;AAAA,EACA,KAAO,EAAA;AAAA,IACL,QAAU,EAAA,EAAA;AAAA,IACV,UAAY,EAAA,KAAA;AAAA,IACZ,aAAe,EAAA,GAAA;AAAA,IACf,OAAS,EAAA;AAAA;AAEb,CAAC,CAAA"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {jsxs,jsx}from'react/jsx-runtime';import {useRef,useMemo,useEffect}from'react';import {Animated,Easing,View,StyleSheet,Image}from'react-native';var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
+
var __spreadValues = (a, b) => {
|
|
9
|
+
for (var prop in b || (b = {}))
|
|
10
|
+
if (__hasOwnProp.call(b, prop))
|
|
11
|
+
__defNormalProp(a, prop, b[prop]);
|
|
12
|
+
if (__getOwnPropSymbols)
|
|
13
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
+
if (__propIsEnum.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
}
|
|
17
|
+
return a;
|
|
18
|
+
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
+
const ICON = require("../assets/icon.png");
|
|
21
|
+
const YANTRA_LOADER_SIZE_DEFAULT = 72;
|
|
22
|
+
const YANTRA_LOADER_SIZE_COMPACT = 40;
|
|
23
|
+
const BASE = YANTRA_LOADER_SIZE_DEFAULT;
|
|
24
|
+
const RING = 62;
|
|
25
|
+
const ICON_SZ = 34;
|
|
26
|
+
function YantraBrandLoader({
|
|
27
|
+
size = BASE
|
|
28
|
+
}) {
|
|
29
|
+
const spin = useRef(new Animated.Value(0)).current;
|
|
30
|
+
const scale = size / BASE;
|
|
31
|
+
const ringLayout = useMemo(() => {
|
|
32
|
+
const ringSize2 = RING * scale;
|
|
33
|
+
const inset2 = (size - ringSize2) / 2;
|
|
34
|
+
return {
|
|
35
|
+
ringSize: ringSize2,
|
|
36
|
+
inset: inset2
|
|
37
|
+
};
|
|
38
|
+
}, [size, scale]);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
const loop = Animated.loop(Animated.timing(spin, {
|
|
41
|
+
toValue: 1,
|
|
42
|
+
duration: 1100,
|
|
43
|
+
easing: Easing.linear,
|
|
44
|
+
useNativeDriver: true
|
|
45
|
+
}));
|
|
46
|
+
loop.start();
|
|
47
|
+
return () => loop.stop();
|
|
48
|
+
}, [spin]);
|
|
49
|
+
const rotate = spin.interpolate({
|
|
50
|
+
inputRange: [0, 1],
|
|
51
|
+
outputRange: ["0deg", "360deg"]
|
|
52
|
+
});
|
|
53
|
+
const {
|
|
54
|
+
ringSize,
|
|
55
|
+
inset
|
|
56
|
+
} = ringLayout;
|
|
57
|
+
const ringBorder = Math.max(2, Math.round(3 * scale));
|
|
58
|
+
return /* @__PURE__ */ jsxs(View, { style: [styles.wrap, {
|
|
59
|
+
width: size,
|
|
60
|
+
height: size
|
|
61
|
+
}], children: [
|
|
62
|
+
/* @__PURE__ */ jsx(Animated.View, { style: [styles.ring, {
|
|
63
|
+
width: ringSize,
|
|
64
|
+
height: ringSize,
|
|
65
|
+
borderRadius: ringSize / 2,
|
|
66
|
+
borderWidth: ringBorder,
|
|
67
|
+
top: inset,
|
|
68
|
+
left: inset,
|
|
69
|
+
transform: [{
|
|
70
|
+
rotate
|
|
71
|
+
}]
|
|
72
|
+
}] }),
|
|
73
|
+
/* @__PURE__ */ jsx(View, { style: styles.iconWrap, children: /* @__PURE__ */ jsx(Image, { source: ICON, style: {
|
|
74
|
+
width: ICON_SZ * scale,
|
|
75
|
+
height: ICON_SZ * scale
|
|
76
|
+
}, resizeMode: "contain", accessibilityIgnoresInvertColors: true }) })
|
|
77
|
+
] });
|
|
78
|
+
}
|
|
79
|
+
const styles = StyleSheet.create({
|
|
80
|
+
wrap: {
|
|
81
|
+
alignItems: "center",
|
|
82
|
+
justifyContent: "center"
|
|
83
|
+
},
|
|
84
|
+
ring: {
|
|
85
|
+
position: "absolute",
|
|
86
|
+
borderColor: "#e5e7eb",
|
|
87
|
+
borderTopColor: "#111827",
|
|
88
|
+
borderRightColor: "#6b7280"
|
|
89
|
+
},
|
|
90
|
+
iconWrap: __spreadProps(__spreadValues({}, StyleSheet.absoluteFillObject), {
|
|
91
|
+
alignItems: "center",
|
|
92
|
+
justifyContent: "center"
|
|
93
|
+
})
|
|
94
|
+
});export{YANTRA_LOADER_SIZE_COMPACT,YANTRA_LOADER_SIZE_DEFAULT,YantraBrandLoader};//# sourceMappingURL=YantraBrandLoader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"YantraBrandLoader.js","sources":["../../src/components/YantraBrandLoader.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef } from 'react';\nimport { Animated, Easing, Image, StyleSheet, View } from 'react-native';\n\nconst ICON = require('../assets/icon.png');\n\n/** Default outer size for full-screen / landing loaders */\nexport const YANTRA_LOADER_SIZE_DEFAULT = 72;\n/** Compact size for composer “sending…” overlay */\nexport const YANTRA_LOADER_SIZE_COMPACT = 40;\n\nconst BASE = YANTRA_LOADER_SIZE_DEFAULT;\nconst RING = 62;\nconst ICON_SZ = 34;\n\nexport interface YantraBrandLoaderProps {\n /** Outer container width/height in px */\n size?: number;\n}\n\n/**\n * Indeterminate circular ring with Yantra icon centered (brand splash / gate screens).\n */\nexport function YantraBrandLoader({ size = BASE }: YantraBrandLoaderProps) {\n const spin = useRef(new Animated.Value(0)).current;\n const scale = size / BASE;\n\n const ringLayout = useMemo(() => {\n const ringSize = RING * scale;\n const inset = (size - ringSize) / 2;\n return { ringSize, inset };\n }, [size, scale]);\n\n useEffect(() => {\n const loop = Animated.loop(\n Animated.timing(spin, {\n toValue: 1,\n duration: 1100,\n easing: Easing.linear,\n useNativeDriver: true,\n }),\n );\n loop.start();\n return () => loop.stop();\n }, [spin]);\n\n const rotate = spin.interpolate({\n inputRange: [0, 1],\n outputRange: ['0deg', '360deg'],\n });\n\n const { ringSize, inset } = ringLayout;\n const ringBorder = Math.max(2, Math.round(3 * scale));\n\n return (\n <View style={[styles.wrap, { width: size, height: size }]}>\n <Animated.View\n style={[\n styles.ring,\n {\n width: ringSize,\n height: ringSize,\n borderRadius: ringSize / 2,\n borderWidth: ringBorder,\n top: inset,\n left: inset,\n transform: [{ rotate }],\n },\n ]}\n />\n <View style={styles.iconWrap}>\n <Image\n source={ICON}\n style={{ width: ICON_SZ * scale, height: ICON_SZ * scale }}\n resizeMode=\"contain\"\n accessibilityIgnoresInvertColors\n />\n </View>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n wrap: {\n alignItems: 'center',\n justifyContent: 'center',\n },\n ring: {\n position: 'absolute',\n borderColor: '#e5e7eb',\n borderTopColor: '#111827',\n borderRightColor: '#6b7280',\n },\n iconWrap: {\n ...StyleSheet.absoluteFillObject,\n alignItems: 'center',\n justifyContent: 'center',\n },\n});\n"],"names":["ringSize","inset"],"mappings":"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"}
|