@ringg/react-native 0.0.1-alpha.9 → 0.2.0
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/dist/index.d.mts +964 -0
- package/dist/index.d.ts +964 -0
- package/dist/index.js +1164 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1129 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +24 -66
- package/LICENSE +0 -21
- package/README.md +0 -250
- package/app.plugin.js +0 -51
- package/lib/module/adapters/index.js +0 -4
- package/lib/module/adapters/index.js.map +0 -1
- package/lib/module/adapters/livekit-rn-adapter.js +0 -216
- package/lib/module/adapters/livekit-rn-adapter.js.map +0 -1
- package/lib/module/components/RinggWidget.js +0 -554
- package/lib/module/components/RinggWidget.js.map +0 -1
- package/lib/module/components/steps/ButtonsStep.js +0 -146
- package/lib/module/components/steps/ButtonsStep.js.map +0 -1
- package/lib/module/components/steps/CalendarStep.js +0 -190
- package/lib/module/components/steps/CalendarStep.js.map +0 -1
- package/lib/module/components/steps/ConfirmationStep.js +0 -175
- package/lib/module/components/steps/ConfirmationStep.js.map +0 -1
- package/lib/module/components/steps/FormStep.js +0 -346
- package/lib/module/components/steps/FormStep.js.map +0 -1
- package/lib/module/components/steps/InteractiveFlow.js +0 -249
- package/lib/module/components/steps/InteractiveFlow.js.map +0 -1
- package/lib/module/components/ui/ActionButton.js +0 -92
- package/lib/module/components/ui/ActionButton.js.map +0 -1
- package/lib/module/components/ui/CallControls.js +0 -168
- package/lib/module/components/ui/CallControls.js.map +0 -1
- package/lib/module/components/ui/FeedbackScreen.js +0 -180
- package/lib/module/components/ui/FeedbackScreen.js.map +0 -1
- package/lib/module/components/ui/Icons.js +0 -294
- package/lib/module/components/ui/Icons.js.map +0 -1
- package/lib/module/components/ui/MessageBubble.js +0 -80
- package/lib/module/components/ui/MessageBubble.js.map +0 -1
- package/lib/module/components/ui/TabSelector.js +0 -80
- package/lib/module/components/ui/TabSelector.js.map +0 -1
- package/lib/module/components/ui/WidgetHeader.js +0 -168
- package/lib/module/components/ui/WidgetHeader.js.map +0 -1
- package/lib/module/context/RinggProvider.js +0 -134
- package/lib/module/context/RinggProvider.js.map +0 -1
- package/lib/module/context/index.js +0 -4
- package/lib/module/context/index.js.map +0 -1
- package/lib/module/globals.d.js +0 -2
- package/lib/module/globals.d.js.map +0 -1
- package/lib/module/hooks/index.js +0 -10
- package/lib/module/hooks/index.js.map +0 -1
- package/lib/module/hooks/useRinggCall.js +0 -259
- package/lib/module/hooks/useRinggCall.js.map +0 -1
- package/lib/module/hooks/useRinggChat.js +0 -141
- package/lib/module/hooks/useRinggChat.js.map +0 -1
- package/lib/module/hooks/useRinggComponents.js +0 -236
- package/lib/module/hooks/useRinggComponents.js.map +0 -1
- package/lib/module/hooks/useRinggFeedback.js +0 -66
- package/lib/module/hooks/useRinggFeedback.js.map +0 -1
- package/lib/module/hooks/useRinggTheme.js +0 -39
- package/lib/module/hooks/useRinggTheme.js.map +0 -1
- package/lib/module/hooks/useRinggTranscripts.js +0 -70
- package/lib/module/hooks/useRinggTranscripts.js.map +0 -1
- package/lib/module/hooks/useRinggWidgetState.js +0 -51
- package/lib/module/hooks/useRinggWidgetState.js.map +0 -1
- package/lib/module/index.js +0 -56
- package/lib/module/index.js.map +0 -1
- package/lib/module/package.json +0 -1
- package/lib/typescript/adapters/index.d.ts +0 -2
- package/lib/typescript/adapters/index.d.ts.map +0 -1
- package/lib/typescript/adapters/livekit-rn-adapter.d.ts +0 -38
- package/lib/typescript/adapters/livekit-rn-adapter.d.ts.map +0 -1
- package/lib/typescript/components/RinggWidget.d.ts +0 -44
- package/lib/typescript/components/RinggWidget.d.ts.map +0 -1
- package/lib/typescript/components/steps/ButtonsStep.d.ts +0 -17
- package/lib/typescript/components/steps/ButtonsStep.d.ts.map +0 -1
- package/lib/typescript/components/steps/CalendarStep.d.ts +0 -16
- package/lib/typescript/components/steps/CalendarStep.d.ts.map +0 -1
- package/lib/typescript/components/steps/ConfirmationStep.d.ts +0 -16
- package/lib/typescript/components/steps/ConfirmationStep.d.ts.map +0 -1
- package/lib/typescript/components/steps/FormStep.d.ts +0 -17
- package/lib/typescript/components/steps/FormStep.d.ts.map +0 -1
- package/lib/typescript/components/steps/InteractiveFlow.d.ts +0 -23
- package/lib/typescript/components/steps/InteractiveFlow.d.ts.map +0 -1
- package/lib/typescript/components/ui/ActionButton.d.ts +0 -22
- package/lib/typescript/components/ui/ActionButton.d.ts.map +0 -1
- package/lib/typescript/components/ui/CallControls.d.ts +0 -22
- package/lib/typescript/components/ui/CallControls.d.ts.map +0 -1
- package/lib/typescript/components/ui/FeedbackScreen.d.ts +0 -24
- package/lib/typescript/components/ui/FeedbackScreen.d.ts.map +0 -1
- package/lib/typescript/components/ui/Icons.d.ts +0 -28
- package/lib/typescript/components/ui/Icons.d.ts.map +0 -1
- package/lib/typescript/components/ui/MessageBubble.d.ts +0 -17
- package/lib/typescript/components/ui/MessageBubble.d.ts.map +0 -1
- package/lib/typescript/components/ui/TabSelector.d.ts +0 -21
- package/lib/typescript/components/ui/TabSelector.d.ts.map +0 -1
- package/lib/typescript/components/ui/WidgetHeader.d.ts +0 -20
- package/lib/typescript/components/ui/WidgetHeader.d.ts.map +0 -1
- package/lib/typescript/context/RinggProvider.d.ts +0 -53
- package/lib/typescript/context/RinggProvider.d.ts.map +0 -1
- package/lib/typescript/context/index.d.ts +0 -3
- package/lib/typescript/context/index.d.ts.map +0 -1
- package/lib/typescript/hooks/index.d.ts +0 -15
- package/lib/typescript/hooks/index.d.ts.map +0 -1
- package/lib/typescript/hooks/useRinggCall.d.ts +0 -41
- package/lib/typescript/hooks/useRinggCall.d.ts.map +0 -1
- package/lib/typescript/hooks/useRinggChat.d.ts +0 -29
- package/lib/typescript/hooks/useRinggChat.d.ts.map +0 -1
- package/lib/typescript/hooks/useRinggComponents.d.ts +0 -52
- package/lib/typescript/hooks/useRinggComponents.d.ts.map +0 -1
- package/lib/typescript/hooks/useRinggFeedback.d.ts +0 -23
- package/lib/typescript/hooks/useRinggFeedback.d.ts.map +0 -1
- package/lib/typescript/hooks/useRinggTheme.d.ts +0 -40
- package/lib/typescript/hooks/useRinggTheme.d.ts.map +0 -1
- package/lib/typescript/hooks/useRinggTranscripts.d.ts +0 -30
- package/lib/typescript/hooks/useRinggTranscripts.d.ts.map +0 -1
- package/lib/typescript/hooks/useRinggWidgetState.d.ts +0 -38
- package/lib/typescript/hooks/useRinggWidgetState.d.ts.map +0 -1
- package/lib/typescript/index.d.ts +0 -44
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/package.json +0 -1
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* RinggProvider — top-level context that holds all core instances.
|
|
5
|
-
*
|
|
6
|
-
* Wraps the widget tree and provides:
|
|
7
|
-
* - LiveKitRNAdapter (room connection, RPC, transcriptions)
|
|
8
|
-
* - RinggApiClient (backend calls)
|
|
9
|
-
* - WidgetStateController (open/close/feedback state machine)
|
|
10
|
-
* - EventBus (host app event dispatch)
|
|
11
|
-
*
|
|
12
|
-
* Consumers can either:
|
|
13
|
-
* 1. Use the pre-built <RinggWidget /> which wraps this automatically
|
|
14
|
-
* 2. Use <RinggProvider> directly with headless hooks for custom UI
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import React, { createContext, useContext, useMemo, useRef, useEffect } from "react";
|
|
18
|
-
import { RinggApiClient, StaticUrlResolver, CallbackEventBus, WidgetStateController, mergeWidgetTheme } from "@ringg/core";
|
|
19
|
-
import { LiveKitRNAdapter } from "../adapters/livekit-rn-adapter.js";
|
|
20
|
-
|
|
21
|
-
// ─── Context Value ───────────────────────────────────────────────────────────
|
|
22
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
23
|
-
const RinggContext = /*#__PURE__*/createContext(null);
|
|
24
|
-
|
|
25
|
-
// ─── Hook to consume context ─────────────────────────────────────────────────
|
|
26
|
-
|
|
27
|
-
export function useRinggContext() {
|
|
28
|
-
const ctx = useContext(RinggContext);
|
|
29
|
-
if (!ctx) {
|
|
30
|
-
throw new Error("useRinggContext must be used within a <RinggProvider>. " + "Wrap your component tree with <RinggProvider config={...}>.");
|
|
31
|
-
}
|
|
32
|
-
return ctx;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// ─── Provider Props ──────────────────────────────────────────────────────────
|
|
36
|
-
|
|
37
|
-
// ─── Default URLs ────────────────────────────────────────────────────────────
|
|
38
|
-
|
|
39
|
-
const DEFAULT_URLS = {
|
|
40
|
-
prod: {
|
|
41
|
-
backendUrl: "https://prod-api.ringg.ai/ca/api/v0",
|
|
42
|
-
livekitUrl: "wss://ringg-ai-prod-r0vhjzhs.livekit.cloud"
|
|
43
|
-
},
|
|
44
|
-
stage: {
|
|
45
|
-
backendUrl: "https://stage-api2.desivocal.com/ca/api/v0",
|
|
46
|
-
livekitUrl: "wss://ringg-ai-ujrjmhgy.livekit.cloud"
|
|
47
|
-
},
|
|
48
|
-
dev: {
|
|
49
|
-
backendUrl: "https://calling-dev.ringg.ai/ca/api/v0",
|
|
50
|
-
livekitUrl: "wss://ringg-ai-dev-92tubwpz.livekit.cloud"
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
// ─── Provider Component ──────────────────────────────────────────────────────
|
|
55
|
-
|
|
56
|
-
export function RinggProvider({
|
|
57
|
-
config,
|
|
58
|
-
urls,
|
|
59
|
-
onEvent,
|
|
60
|
-
children
|
|
61
|
-
}) {
|
|
62
|
-
// Stable refs for instances that should persist across re-renders
|
|
63
|
-
const livekitRef = useRef(null);
|
|
64
|
-
const eventBusRef = useRef(null);
|
|
65
|
-
|
|
66
|
-
// Create stable instances on first render
|
|
67
|
-
if (!livekitRef.current) {
|
|
68
|
-
livekitRef.current = new LiveKitRNAdapter();
|
|
69
|
-
}
|
|
70
|
-
if (!eventBusRef.current) {
|
|
71
|
-
eventBusRef.current = new CallbackEventBus();
|
|
72
|
-
}
|
|
73
|
-
const livekit = livekitRef.current;
|
|
74
|
-
const eventBus = eventBusRef.current;
|
|
75
|
-
|
|
76
|
-
// Resolve environment URLs
|
|
77
|
-
const resolvedUrls = useMemo(() => {
|
|
78
|
-
const merged = {
|
|
79
|
-
...DEFAULT_URLS,
|
|
80
|
-
...urls
|
|
81
|
-
};
|
|
82
|
-
return merged;
|
|
83
|
-
}, [urls]);
|
|
84
|
-
const mode = config.mode ?? "prod";
|
|
85
|
-
const livekitUrl = resolvedUrls[mode]?.livekitUrl ?? DEFAULT_URLS.prod.livekitUrl;
|
|
86
|
-
|
|
87
|
-
// Rebuild API client when config changes (mode, xApiKey)
|
|
88
|
-
const api = useMemo(() => {
|
|
89
|
-
return new RinggApiClient({
|
|
90
|
-
urlResolver: new StaticUrlResolver(resolvedUrls),
|
|
91
|
-
mode,
|
|
92
|
-
xApiKey: config.xApiKey
|
|
93
|
-
});
|
|
94
|
-
}, [mode, config.xApiKey, resolvedUrls]);
|
|
95
|
-
|
|
96
|
-
// Widget state controller — created once, persists
|
|
97
|
-
const widgetState = useMemo(() => new WidgetStateController(eventBus, config.defaultTab ?? "audio"),
|
|
98
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
99
|
-
[]);
|
|
100
|
-
|
|
101
|
-
// Resolved theme
|
|
102
|
-
const theme = useMemo(() => mergeWidgetTheme(config.theme), [config.theme]);
|
|
103
|
-
|
|
104
|
-
// Forward events to onEvent callback if provided
|
|
105
|
-
useEffect(() => {
|
|
106
|
-
if (!onEvent) return;
|
|
107
|
-
const unsubs = [eventBus.on("ringg:widget_status", p => onEvent("ringg:widget_status", p)), eventBus.on("ringg:conversation_status", p => onEvent("ringg:conversation_status", p)), eventBus.on("ringg:feedback_status", p => onEvent("ringg:feedback_status", p)), eventBus.on("ringg:calendar_booking", p => onEvent("ringg:calendar_booking", p)), eventBus.on("ringg:component_acknowledgement", p => onEvent("ringg:component_acknowledgement", p))];
|
|
108
|
-
return () => unsubs.forEach(unsub => unsub());
|
|
109
|
-
}, [eventBus, onEvent]);
|
|
110
|
-
|
|
111
|
-
// Cleanup on unmount
|
|
112
|
-
useEffect(() => {
|
|
113
|
-
return () => {
|
|
114
|
-
livekit.dispose();
|
|
115
|
-
widgetState.dispose();
|
|
116
|
-
eventBus.off();
|
|
117
|
-
};
|
|
118
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
119
|
-
}, []);
|
|
120
|
-
const contextValue = useMemo(() => ({
|
|
121
|
-
config,
|
|
122
|
-
livekit,
|
|
123
|
-
api,
|
|
124
|
-
eventBus,
|
|
125
|
-
widgetState,
|
|
126
|
-
theme,
|
|
127
|
-
livekitUrl
|
|
128
|
-
}), [config, livekit, api, eventBus, widgetState, theme, livekitUrl]);
|
|
129
|
-
return /*#__PURE__*/_jsx(RinggContext.Provider, {
|
|
130
|
-
value: contextValue,
|
|
131
|
-
children: children
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
//# sourceMappingURL=RinggProvider.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["React","createContext","useContext","useMemo","useRef","useEffect","RinggApiClient","StaticUrlResolver","CallbackEventBus","WidgetStateController","mergeWidgetTheme","LiveKitRNAdapter","jsx","_jsx","RinggContext","useRinggContext","ctx","Error","DEFAULT_URLS","prod","backendUrl","livekitUrl","stage","dev","RinggProvider","config","urls","onEvent","children","livekitRef","eventBusRef","current","livekit","eventBus","resolvedUrls","merged","mode","api","urlResolver","xApiKey","widgetState","defaultTab","theme","unsubs","on","p","forEach","unsub","dispose","off","contextValue","Provider","value"],"sourceRoot":"../../../src","sources":["context/RinggProvider.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["RinggProvider","useRinggContext"],"sourceRoot":"../../../src","sources":["context/index.ts"],"mappings":";;AAAA,SAASA,aAAa,EAAEC,eAAe,QAAQ,oBAAiB","ignoreList":[]}
|
package/lib/module/globals.d.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":[],"sourceRoot":"../../src","sources":["globals.d.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
export { useRinggCall } from "./useRinggCall.js";
|
|
4
|
-
export { useRinggChat } from "./useRinggChat.js";
|
|
5
|
-
export { useRinggTranscripts } from "./useRinggTranscripts.js";
|
|
6
|
-
export { useRinggComponents } from "./useRinggComponents.js";
|
|
7
|
-
export { useRinggWidgetState } from "./useRinggWidgetState.js";
|
|
8
|
-
export { useRinggFeedback } from "./useRinggFeedback.js";
|
|
9
|
-
export { useRinggTheme } from "./useRinggTheme.js";
|
|
10
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["useRinggCall","useRinggChat","useRinggTranscripts","useRinggComponents","useRinggWidgetState","useRinggFeedback","useRinggTheme"],"sourceRoot":"../../../src","sources":["hooks/index.ts"],"mappings":";;AAAA,SAASA,YAAY,QAAQ,mBAAgB;AAG7C,SAASC,YAAY,QAAQ,mBAAgB;AAG7C,SAASC,mBAAmB,QAAQ,0BAAuB;AAG3D,SAASC,kBAAkB,QAAQ,yBAAsB;AAGzD,SAASC,mBAAmB,QAAQ,0BAAuB;AAG3D,SAASC,gBAAgB,QAAQ,uBAAoB;AAGrD,SAASC,aAAa,QAAQ,oBAAiB","ignoreList":[]}
|
|
@@ -1,259 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* useRinggCall — headless hook to start/end calls with Ringg AI agents.
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* ```tsx
|
|
8
|
-
* const { startCall, endCall, isConnected, isMicEnabled, toggleMic } = useRinggCall();
|
|
9
|
-
*
|
|
10
|
-
* <Button onPress={() => startCall("audio")} title="Call Agent" />
|
|
11
|
-
* <Button onPress={toggleMic} title={isMicEnabled ? "Mute" : "Unmute"} />
|
|
12
|
-
* <Button onPress={endCall} title="Hang Up" />
|
|
13
|
-
* ```
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
17
|
-
import { Platform, PermissionsAndroid } from "react-native";
|
|
18
|
-
import { isAgentIdentity } from "@ringg/core";
|
|
19
|
-
import { useRinggContext } from "../context/RinggProvider.js";
|
|
20
|
-
|
|
21
|
-
// Lazily resolve AudioSession from @livekit/react-native.
|
|
22
|
-
// This is a dep so it will always be installed, but we wrap in try/catch
|
|
23
|
-
// for safety in case the native module isn't linked (e.g. Expo Go).
|
|
24
|
-
let _AudioSession = null;
|
|
25
|
-
function getAudioSession() {
|
|
26
|
-
if (_AudioSession) return _AudioSession;
|
|
27
|
-
if (Platform.OS === "web") return null;
|
|
28
|
-
try {
|
|
29
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
30
|
-
const mod = require("@livekit/react-native");
|
|
31
|
-
_AudioSession = mod.AudioSession ?? mod.default?.AudioSession ?? null;
|
|
32
|
-
return _AudioSession;
|
|
33
|
-
} catch {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Request microphone permission at runtime.
|
|
40
|
-
* - iOS: triggers the system permission prompt via getUserMedia
|
|
41
|
-
* - Android: uses PermissionsAndroid.request(RECORD_AUDIO)
|
|
42
|
-
* Returns true if granted, false otherwise.
|
|
43
|
-
*/
|
|
44
|
-
async function requestMicPermission() {
|
|
45
|
-
try {
|
|
46
|
-
if (Platform.OS === "android") {
|
|
47
|
-
const result = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.RECORD_AUDIO, {
|
|
48
|
-
title: "Microphone Permission",
|
|
49
|
-
message: "This app needs microphone access for voice calls.",
|
|
50
|
-
buttonPositive: "Allow",
|
|
51
|
-
buttonNegative: "Deny"
|
|
52
|
-
});
|
|
53
|
-
return result === PermissionsAndroid.RESULTS.GRANTED;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// iOS + other: trigger getUserMedia which shows the system permission prompt.
|
|
57
|
-
// registerGlobals() from @livekit/react-native patches navigator.mediaDevices.
|
|
58
|
-
const nav = typeof globalThis !== "undefined" ? globalThis.navigator : undefined;
|
|
59
|
-
if (nav?.mediaDevices?.getUserMedia) {
|
|
60
|
-
const stream = await nav.mediaDevices.getUserMedia({
|
|
61
|
-
audio: true
|
|
62
|
-
});
|
|
63
|
-
// Stop tracks immediately — we just needed the permission prompt
|
|
64
|
-
stream.getTracks().forEach(t => t.stop());
|
|
65
|
-
return true;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Fallback: assume granted (LiveKit will handle the error if not)
|
|
69
|
-
return true;
|
|
70
|
-
} catch {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
export function useRinggCall() {
|
|
75
|
-
const {
|
|
76
|
-
config,
|
|
77
|
-
livekit,
|
|
78
|
-
api,
|
|
79
|
-
widgetState,
|
|
80
|
-
livekitUrl
|
|
81
|
-
} = useRinggContext();
|
|
82
|
-
const [connectionState, setConnectionState] = useState("disconnected");
|
|
83
|
-
const [isLoading, setIsLoading] = useState(false);
|
|
84
|
-
const [callMode, setCallMode] = useState(config.defaultTab ?? "audio");
|
|
85
|
-
const [callId, setCallId] = useState(null);
|
|
86
|
-
const [error, setError] = useState(null);
|
|
87
|
-
const [isMicEnabled, setIsMicEnabled] = useState(false);
|
|
88
|
-
const [runtimeSlashCommands, setRuntimeSlashCommands] = useState([]);
|
|
89
|
-
const callIdRef = useRef(null);
|
|
90
|
-
const callModeRef = useRef(callMode);
|
|
91
|
-
callModeRef.current = callMode;
|
|
92
|
-
|
|
93
|
-
// Track connection state changes
|
|
94
|
-
useEffect(() => {
|
|
95
|
-
const unsub = livekit.onConnectionStateChange(state => {
|
|
96
|
-
setConnectionState(state);
|
|
97
|
-
// Reset mic state on disconnect
|
|
98
|
-
if (state === "disconnected") {
|
|
99
|
-
setIsMicEnabled(false);
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
return unsub;
|
|
103
|
-
}, [livekit]);
|
|
104
|
-
|
|
105
|
-
// Handle call end (internal)
|
|
106
|
-
const handleEndCall = useCallback(() => {
|
|
107
|
-
const currentCallId = callIdRef.current;
|
|
108
|
-
const currentMode = callModeRef.current;
|
|
109
|
-
if (currentCallId) {
|
|
110
|
-
widgetState.dispatchConversationEnd(currentMode, currentCallId);
|
|
111
|
-
}
|
|
112
|
-
livekit.disconnect();
|
|
113
|
-
|
|
114
|
-
// Stop native AudioSession on disconnect
|
|
115
|
-
const audioSession = getAudioSession();
|
|
116
|
-
if (audioSession) {
|
|
117
|
-
audioSession.stopAudioSession().catch(() => {});
|
|
118
|
-
}
|
|
119
|
-
setRuntimeSlashCommands([]);
|
|
120
|
-
setIsMicEnabled(false);
|
|
121
|
-
setConnectionState("disconnected");
|
|
122
|
-
widgetState.showFeedback();
|
|
123
|
-
}, [livekit, widgetState]);
|
|
124
|
-
|
|
125
|
-
// Auto-end call on agent disconnect or room disconnect
|
|
126
|
-
useEffect(() => {
|
|
127
|
-
const unsubParticipant = livekit.onParticipantDisconnected(identity => {
|
|
128
|
-
if (isAgentIdentity(identity)) {
|
|
129
|
-
handleEndCall();
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
const unsubRoom = livekit.onDisconnected(() => {
|
|
133
|
-
handleEndCall();
|
|
134
|
-
});
|
|
135
|
-
return () => {
|
|
136
|
-
unsubParticipant();
|
|
137
|
-
unsubRoom();
|
|
138
|
-
};
|
|
139
|
-
}, [livekit, handleEndCall]);
|
|
140
|
-
const startCall = useCallback(async mediaType => {
|
|
141
|
-
setIsLoading(true);
|
|
142
|
-
setError(null);
|
|
143
|
-
setCallMode(mediaType);
|
|
144
|
-
callModeRef.current = mediaType;
|
|
145
|
-
widgetState.setCallMode(mediaType);
|
|
146
|
-
try {
|
|
147
|
-
// Get LiveKit token from backend
|
|
148
|
-
const response = await api.startWebcall({
|
|
149
|
-
agentId: config.agentId,
|
|
150
|
-
variables: config.variables,
|
|
151
|
-
mediaType
|
|
152
|
-
});
|
|
153
|
-
callIdRef.current = response.call_id;
|
|
154
|
-
setCallId(response.call_id);
|
|
155
|
-
widgetState.setCurrentCallId(response.call_id);
|
|
156
|
-
|
|
157
|
-
// Capture runtime slash commands
|
|
158
|
-
if (Array.isArray(response.enabled_slash_commands)) {
|
|
159
|
-
setRuntimeSlashCommands(response.enabled_slash_commands);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// For audio mode, request mic permission BEFORE connecting
|
|
163
|
-
// so the permission prompt doesn't race with room setup
|
|
164
|
-
if (mediaType === "audio") {
|
|
165
|
-
const hasPermission = await requestMicPermission();
|
|
166
|
-
if (!hasPermission) {
|
|
167
|
-
setError("Microphone permission denied. Please allow mic access in Settings.");
|
|
168
|
-
setIsLoading(false);
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Configure and start native AudioSession before connecting.
|
|
174
|
-
// configureAudio sets the iOS audio category/mode (playAndRecord with speaker)
|
|
175
|
-
// and Android audio attributes. startAudioSession activates it.
|
|
176
|
-
// This MUST happen before room.connect() or setMicrophoneEnabled().
|
|
177
|
-
const audioSession = getAudioSession();
|
|
178
|
-
if (audioSession) {
|
|
179
|
-
try {
|
|
180
|
-
await audioSession.configureAudio({
|
|
181
|
-
ios: {
|
|
182
|
-
defaultOutput: "speaker"
|
|
183
|
-
},
|
|
184
|
-
android: {
|
|
185
|
-
preferredOutputList: ["speaker", "bluetooth", "headset", "earpiece"],
|
|
186
|
-
audioTypeOptions: {
|
|
187
|
-
manageAudioFocus: true,
|
|
188
|
-
audioMode: "inCommunication",
|
|
189
|
-
audioFocusMode: "gain",
|
|
190
|
-
audioAttributesUsageType: "voiceCommunication",
|
|
191
|
-
audioAttributesContentType: "speech",
|
|
192
|
-
audioStreamType: "voiceCall"
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
await audioSession.startAudioSession();
|
|
197
|
-
} catch {
|
|
198
|
-
// AudioSession start failure is non-fatal on some devices
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Connect to LiveKit room using URL from provider
|
|
203
|
-
await livekit.connect(livekitUrl, response.user_token);
|
|
204
|
-
|
|
205
|
-
// Enable mic for audio mode (permission already granted above)
|
|
206
|
-
if (mediaType === "audio") {
|
|
207
|
-
try {
|
|
208
|
-
await livekit.setMicrophoneEnabled(true);
|
|
209
|
-
setIsMicEnabled(true);
|
|
210
|
-
} catch {
|
|
211
|
-
setError("Microphone access failed. Check permissions.");
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
widgetState.dispatchConversationStart(mediaType, response.call_id);
|
|
215
|
-
} catch (err) {
|
|
216
|
-
// If connection failed, stop audio session to clean up
|
|
217
|
-
const audioSession = getAudioSession();
|
|
218
|
-
if (audioSession) {
|
|
219
|
-
audioSession.stopAudioSession().catch(() => {});
|
|
220
|
-
}
|
|
221
|
-
setError(err.message);
|
|
222
|
-
} finally {
|
|
223
|
-
setIsLoading(false);
|
|
224
|
-
}
|
|
225
|
-
}, [api, config.agentId, config.variables, livekit, livekitUrl, widgetState]);
|
|
226
|
-
const endCall = useCallback(async () => {
|
|
227
|
-
setIsLoading(true);
|
|
228
|
-
try {
|
|
229
|
-
handleEndCall();
|
|
230
|
-
} finally {
|
|
231
|
-
setIsLoading(false);
|
|
232
|
-
}
|
|
233
|
-
}, [handleEndCall]);
|
|
234
|
-
const toggleMic = useCallback(async () => {
|
|
235
|
-
try {
|
|
236
|
-
const newState = !livekit.isMicrophoneEnabled();
|
|
237
|
-
await livekit.setMicrophoneEnabled(newState);
|
|
238
|
-
setIsMicEnabled(newState);
|
|
239
|
-
} catch {
|
|
240
|
-
// Toggle failure — mic state may be stale
|
|
241
|
-
}
|
|
242
|
-
}, [livekit]);
|
|
243
|
-
const clearError = useCallback(() => setError(null), []);
|
|
244
|
-
return {
|
|
245
|
-
startCall,
|
|
246
|
-
endCall,
|
|
247
|
-
connectionState,
|
|
248
|
-
isConnected: connectionState === "connected",
|
|
249
|
-
isLoading,
|
|
250
|
-
callMode,
|
|
251
|
-
callId,
|
|
252
|
-
isMicEnabled,
|
|
253
|
-
toggleMic,
|
|
254
|
-
error,
|
|
255
|
-
clearError,
|
|
256
|
-
runtimeSlashCommands
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
//# sourceMappingURL=useRinggCall.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useEffect","useRef","useState","Platform","PermissionsAndroid","isAgentIdentity","useRinggContext","_AudioSession","getAudioSession","OS","mod","require","AudioSession","default","requestMicPermission","result","request","PERMISSIONS","RECORD_AUDIO","title","message","buttonPositive","buttonNegative","RESULTS","GRANTED","nav","globalThis","navigator","undefined","mediaDevices","getUserMedia","stream","audio","getTracks","forEach","t","stop","useRinggCall","config","livekit","api","widgetState","livekitUrl","connectionState","setConnectionState","isLoading","setIsLoading","callMode","setCallMode","defaultTab","callId","setCallId","error","setError","isMicEnabled","setIsMicEnabled","runtimeSlashCommands","setRuntimeSlashCommands","callIdRef","callModeRef","current","unsub","onConnectionStateChange","state","handleEndCall","currentCallId","currentMode","dispatchConversationEnd","disconnect","audioSession","stopAudioSession","catch","showFeedback","unsubParticipant","onParticipantDisconnected","identity","unsubRoom","onDisconnected","startCall","mediaType","response","startWebcall","agentId","variables","call_id","setCurrentCallId","Array","isArray","enabled_slash_commands","hasPermission","configureAudio","ios","defaultOutput","android","preferredOutputList","audioTypeOptions","manageAudioFocus","audioMode","audioFocusMode","audioAttributesUsageType","audioAttributesContentType","audioStreamType","startAudioSession","connect","user_token","setMicrophoneEnabled","dispatchConversationStart","err","endCall","toggleMic","newState","isMicrophoneEnabled","clearError","isConnected"],"sourceRoot":"../../../src","sources":["hooks/useRinggCall.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* useRinggChat — headless hook for text chat with the AI agent.
|
|
5
|
-
*
|
|
6
|
-
* Handles:
|
|
7
|
-
* - Receiving messages from the agent via LiveKit text streams
|
|
8
|
-
* - Sending messages from the user via LiveKit chat
|
|
9
|
-
* - Message history management
|
|
10
|
-
*
|
|
11
|
-
* Usage:
|
|
12
|
-
* ```tsx
|
|
13
|
-
* const { messages, sendMessage } = useRinggChat();
|
|
14
|
-
*
|
|
15
|
-
* <FlatList data={messages} renderItem={({ item }) => <MessageBubble message={item} />} />
|
|
16
|
-
* <TextInput onSubmitEditing={(e) => sendMessage(e.nativeEvent.text)} />
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
import { useCallback, useEffect, useState } from "react";
|
|
21
|
-
import { isAgentIdentity } from "@ringg/core";
|
|
22
|
-
import { useRinggContext } from "../context/RinggProvider.js";
|
|
23
|
-
export function useRinggChat() {
|
|
24
|
-
const {
|
|
25
|
-
livekit
|
|
26
|
-
} = useRinggContext();
|
|
27
|
-
const [messages, setMessages] = useState([]);
|
|
28
|
-
const [connState, setConnState] = useState("disconnected");
|
|
29
|
-
|
|
30
|
-
// Track connection state to register/unregister handlers
|
|
31
|
-
useEffect(() => {
|
|
32
|
-
const unsub = livekit.onConnectionStateChange(state => {
|
|
33
|
-
setConnState(state);
|
|
34
|
-
});
|
|
35
|
-
// Set initial state
|
|
36
|
-
setConnState(livekit.getConnectionState());
|
|
37
|
-
return unsub;
|
|
38
|
-
}, [livekit]);
|
|
39
|
-
|
|
40
|
-
// Helper to deduplicate and merge a new message into state
|
|
41
|
-
const mergeMessage = useCallback(msg => {
|
|
42
|
-
setMessages(prev => {
|
|
43
|
-
const seen = new Set();
|
|
44
|
-
return [...prev, msg].filter(m => !seen.has(m.timestamp) && seen.add(m.timestamp)).sort((a, b) => a.timestamp - b.timestamp);
|
|
45
|
-
});
|
|
46
|
-
}, []);
|
|
47
|
-
|
|
48
|
-
// Listen for incoming text streams from the agent via "lk.transcription".
|
|
49
|
-
// This is the primary (and only) channel the agent uses to send replies,
|
|
50
|
-
// matching CDN behavior exactly.
|
|
51
|
-
//
|
|
52
|
-
// NOTE: We track connState but only use it as a trigger — the handler
|
|
53
|
-
// registration is idempotent (unregister first, then register).
|
|
54
|
-
useEffect(() => {
|
|
55
|
-
if (connState !== "connected") return;
|
|
56
|
-
|
|
57
|
-
// Unregister any stale handler first (safe even if none was registered)
|
|
58
|
-
try {
|
|
59
|
-
livekit.unregisterTextStreamHandler("lk.transcription");
|
|
60
|
-
} catch {
|
|
61
|
-
// no-op
|
|
62
|
-
}
|
|
63
|
-
try {
|
|
64
|
-
livekit.registerTextStreamHandler("lk.transcription", info => {
|
|
65
|
-
const isAgent = isAgentIdentity(info.participantIdentity);
|
|
66
|
-
mergeMessage({
|
|
67
|
-
message: info.message,
|
|
68
|
-
isSelf: !isAgent,
|
|
69
|
-
name: isAgent ? "Agent" : "You",
|
|
70
|
-
timestamp: Date.now() + Math.random() * 0.001
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
} catch {
|
|
74
|
-
// Registration may fail if room is disconnecting — safe to ignore
|
|
75
|
-
}
|
|
76
|
-
return () => {
|
|
77
|
-
try {
|
|
78
|
-
livekit.unregisterTextStreamHandler("lk.transcription");
|
|
79
|
-
} catch {
|
|
80
|
-
// handler may not have been registered
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
}, [livekit, connState, mergeMessage]);
|
|
84
|
-
const sendMessage = useCallback(async text => {
|
|
85
|
-
if (!text.trim()) return;
|
|
86
|
-
|
|
87
|
-
// Add local message immediately for optimistic UI
|
|
88
|
-
const localMsg = {
|
|
89
|
-
message: text,
|
|
90
|
-
isSelf: true,
|
|
91
|
-
name: "You",
|
|
92
|
-
timestamp: Date.now()
|
|
93
|
-
};
|
|
94
|
-
setMessages(prev => [...prev, localMsg]);
|
|
95
|
-
|
|
96
|
-
// Send via LiveKit's sendText API on topic "lk.chat".
|
|
97
|
-
// This matches the CDN's useChat().send which uses DataTopic.CHAT = "lk.chat".
|
|
98
|
-
// We also send a legacy publishData fallback on "lk-chat-topic" for older servers.
|
|
99
|
-
try {
|
|
100
|
-
const room = livekit.getRoom();
|
|
101
|
-
const msgId = `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
102
|
-
const timestamp = Date.now();
|
|
103
|
-
|
|
104
|
-
// Primary: new Data Streams API
|
|
105
|
-
await room.localParticipant.sendText(text, {
|
|
106
|
-
topic: "lk.chat"
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Legacy fallback: publishData with JSON-encoded payload on "lk-chat-topic"
|
|
110
|
-
try {
|
|
111
|
-
const legacyPayload = JSON.stringify({
|
|
112
|
-
id: msgId,
|
|
113
|
-
timestamp,
|
|
114
|
-
message: text
|
|
115
|
-
});
|
|
116
|
-
const encoded = new TextEncoder().encode(legacyPayload);
|
|
117
|
-
await room.localParticipant.publishData(encoded, {
|
|
118
|
-
reliable: true,
|
|
119
|
-
topic: "lk-chat-topic"
|
|
120
|
-
});
|
|
121
|
-
} catch {
|
|
122
|
-
// Legacy send is best-effort — ignore errors
|
|
123
|
-
}
|
|
124
|
-
} catch {
|
|
125
|
-
// Send failure is non-fatal — message was already shown optimistically
|
|
126
|
-
}
|
|
127
|
-
}, [livekit]);
|
|
128
|
-
const clearMessages = useCallback(() => {
|
|
129
|
-
setMessages([]);
|
|
130
|
-
}, []);
|
|
131
|
-
const addComponentMessage = useCallback(message => {
|
|
132
|
-
setMessages(prev => [...prev, message]);
|
|
133
|
-
}, []);
|
|
134
|
-
return {
|
|
135
|
-
messages,
|
|
136
|
-
sendMessage,
|
|
137
|
-
clearMessages,
|
|
138
|
-
addComponentMessage
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
//# sourceMappingURL=useRinggChat.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["useCallback","useEffect","useState","isAgentIdentity","useRinggContext","useRinggChat","livekit","messages","setMessages","connState","setConnState","unsub","onConnectionStateChange","state","getConnectionState","mergeMessage","msg","prev","seen","Set","filter","m","has","timestamp","add","sort","a","b","unregisterTextStreamHandler","registerTextStreamHandler","info","isAgent","participantIdentity","message","isSelf","name","Date","now","Math","random","sendMessage","text","trim","localMsg","room","getRoom","msgId","toString","slice","localParticipant","sendText","topic","legacyPayload","JSON","stringify","id","encoded","TextEncoder","encode","publishData","reliable","clearMessages","addComponentMessage"],"sourceRoot":"../../../src","sources":["hooks/useRinggChat.ts"],"mappings":"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","ignoreList":[]}
|