botschat 0.1.16 → 0.1.17
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/package.json +4 -1
- package/packages/api/src/index.ts +10 -2
- package/packages/plugin/dist/src/ws-client.d.ts.map +1 -1
- package/packages/plugin/dist/src/ws-client.js +11 -6
- package/packages/plugin/dist/src/ws-client.js.map +1 -1
- package/packages/plugin/package.json +1 -1
- package/packages/web/dist/assets/{index-CLKSdbmx.css → index-B5GU1yVt.css} +1 -1
- package/packages/web/dist/assets/index-CO9YgLst.js +2 -0
- package/packages/web/dist/assets/index-ClDrCe_c.js +1 -0
- package/packages/web/dist/assets/{index--A7c71kf.js → index-D3T7sc-R.js} +1 -1
- package/packages/web/dist/assets/index-DPEosppm.js +2 -0
- package/packages/web/dist/assets/{index-Cd5GHqU6.js → index-DzYqprDN.js} +1 -1
- package/packages/web/dist/assets/index-IVUdSd9w.js +1516 -0
- package/packages/web/dist/assets/{index.esm-Dc_1yrX1.js → index.esm-COzWPkKi.js} +1 -1
- package/packages/web/dist/assets/{web-CDcVasbM.js → web-CxXbaApe.js} +1 -1
- package/packages/web/dist/assets/{web-D_QoLpUi.js → web-DFQypSd0.js} +1 -1
- package/packages/web/dist/index.html +2 -2
- package/packages/web/dist/sw.js +9 -1
- package/packages/web/src/App.tsx +10 -1
- package/packages/web/src/api.ts +5 -3
- package/packages/web/src/components/ChatWindow.tsx +5 -1
- package/packages/web/src/components/CronSidebar.tsx +5 -1
- package/packages/web/src/components/LoginPage.tsx +3 -1
- package/packages/web/src/components/OnboardingPage.tsx +3 -1
- package/packages/web/src/components/SessionTabs.tsx +5 -1
- package/packages/web/src/components/Sidebar.tsx +8 -2
- package/packages/web/src/components/TaskBar.tsx +5 -1
- package/packages/web/src/components/ThreadPanel.tsx +5 -1
- package/packages/web/src/firebase.ts +3 -2
- package/packages/web/src/hooks/useIMEComposition.ts +36 -0
- package/packages/web/src/main.tsx +3 -2
- package/packages/web/src/push.ts +88 -1
- package/packages/web/src/ws.ts +4 -3
- package/packages/web/dist/assets/index-CEStVU9o.js +0 -1516
- package/packages/web/dist/assets/index-D3Vfl8Ll.js +0 -2
- package/packages/web/dist/assets/index-DUpmW4Ay.js +0 -2
- package/packages/web/dist/assets/index-DfBArjKG.js +0 -1
package/packages/web/src/push.ts
CHANGED
|
@@ -96,11 +96,96 @@ export async function clearE2eKeyFromSW(): Promise<void> {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
// ---- macOS native notification bridge ----
|
|
100
|
+
|
|
101
|
+
declare global {
|
|
102
|
+
interface Window {
|
|
103
|
+
__BOTSCHAT_NATIVE__?: boolean;
|
|
104
|
+
__BOTSCHAT_PLATFORM__?: string;
|
|
105
|
+
__BOTSCHAT_NATIVE_NOTIFY__?: (payload: {
|
|
106
|
+
title: string;
|
|
107
|
+
body: string;
|
|
108
|
+
sessionKey?: string;
|
|
109
|
+
}) => void;
|
|
110
|
+
__BOTSCHAT_NATIVE_REQUEST_PERMISSION__?: () => void;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function isMacOSNative(): boolean {
|
|
115
|
+
return !!(window.__BOTSCHAT_NATIVE__ && window.__BOTSCHAT_PLATFORM__ === "macos");
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function initMacOSPush(): Promise<void> {
|
|
119
|
+
try {
|
|
120
|
+
window.__BOTSCHAT_NATIVE_REQUEST_PERMISSION__?.();
|
|
121
|
+
dlog.info("Push", "macOS native notification permission requested");
|
|
122
|
+
} catch (err) {
|
|
123
|
+
dlog.error("Push", "macOS notification init failed", err);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Show a native macOS notification when a message arrives via WS and
|
|
129
|
+
* the window is not focused. Call this from the WS message handler.
|
|
130
|
+
*/
|
|
131
|
+
export function notifyIfBackground(msg: {
|
|
132
|
+
type: string;
|
|
133
|
+
text?: string;
|
|
134
|
+
caption?: string;
|
|
135
|
+
sessionKey?: string;
|
|
136
|
+
agentName?: string;
|
|
137
|
+
}): void {
|
|
138
|
+
if (!isMacOSNative()) return;
|
|
139
|
+
if (!document.hidden && document.hasFocus()) return;
|
|
140
|
+
if (!window.__BOTSCHAT_NATIVE_NOTIFY__) return;
|
|
141
|
+
|
|
142
|
+
let body = "";
|
|
143
|
+
const title = msg.agentName || "BotsChat";
|
|
144
|
+
|
|
145
|
+
if (msg.type === "agent.text" && msg.text) {
|
|
146
|
+
body = msg.text.length > 200 ? msg.text.slice(0, 200) + "…" : msg.text;
|
|
147
|
+
} else if (msg.type === "agent.media") {
|
|
148
|
+
body = msg.caption || "Sent a media file";
|
|
149
|
+
} else {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
window.__BOTSCHAT_NATIVE_NOTIFY__({ title, body, sessionKey: msg.sessionKey });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ---- Service Worker message listener (notification click → navigation) ----
|
|
157
|
+
|
|
158
|
+
function setupSWMessageListener(): void {
|
|
159
|
+
if (!("serviceWorker" in navigator)) return;
|
|
160
|
+
navigator.serviceWorker.addEventListener("message", (event) => {
|
|
161
|
+
if (event.data?.type === "push-nav" && event.data.sessionKey) {
|
|
162
|
+
dlog.info("Push", `SW postMessage push-nav: ${event.data.sessionKey}`);
|
|
163
|
+
firePushNav(event.data.sessionKey);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Also check URL for push_session param (when SW opens a new window)
|
|
168
|
+
const params = new URLSearchParams(window.location.search);
|
|
169
|
+
const pushSession = params.get("push_session");
|
|
170
|
+
if (pushSession) {
|
|
171
|
+
dlog.info("Push", `URL push_session param: ${pushSession}`);
|
|
172
|
+
firePushNav(pushSession);
|
|
173
|
+
// Clean up the URL parameter
|
|
174
|
+
params.delete("push_session");
|
|
175
|
+
const clean = params.toString();
|
|
176
|
+
const newUrl = window.location.pathname + (clean ? "?" + clean : "") + window.location.hash;
|
|
177
|
+
window.history.replaceState({}, "", newUrl);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
99
181
|
// ---- Push initialization ----
|
|
100
182
|
|
|
101
183
|
export async function initPushNotifications(): Promise<void> {
|
|
102
184
|
if (initialized) return;
|
|
103
185
|
|
|
186
|
+
// Listen for SW notification-click messages (must be before any early return)
|
|
187
|
+
setupSWMessageListener();
|
|
188
|
+
|
|
104
189
|
// Sync E2E key so push notifications can be decrypted
|
|
105
190
|
await syncE2eKeyToSW();
|
|
106
191
|
|
|
@@ -109,7 +194,9 @@ export async function initPushNotifications(): Promise<void> {
|
|
|
109
194
|
syncE2eKeyToSW().catch(() => {});
|
|
110
195
|
});
|
|
111
196
|
|
|
112
|
-
if (
|
|
197
|
+
if (isMacOSNative()) {
|
|
198
|
+
await initMacOSPush();
|
|
199
|
+
} else if (Capacitor.isNativePlatform()) {
|
|
113
200
|
await initNativePush();
|
|
114
201
|
} else {
|
|
115
202
|
await initWebPush();
|
package/packages/web/src/ws.ts
CHANGED
|
@@ -35,10 +35,11 @@ export class BotsChatWSClient {
|
|
|
35
35
|
connect(): void {
|
|
36
36
|
this.intentionalClose = false;
|
|
37
37
|
|
|
38
|
-
// In
|
|
39
|
-
// use the full production WebSocket URL.
|
|
38
|
+
// In native apps (Capacitor or macOS), the WebView runs from a custom
|
|
39
|
+
// scheme so we must use the full production WebSocket URL.
|
|
40
|
+
const isNative = Capacitor.isNativePlatform() || !!(window as any).__BOTSCHAT_NATIVE__;
|
|
40
41
|
let url: string;
|
|
41
|
-
if (
|
|
42
|
+
if (isNative) {
|
|
42
43
|
url = `wss://console.botschat.app/api/ws/${this.opts.userId}/${this.opts.sessionId}`;
|
|
43
44
|
} else {
|
|
44
45
|
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|