ape-im-sdk-react 1.0.0 → 1.0.3
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/README.md +23 -4
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +39 -14
- package/dist/index.mjs +39 -14
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -27,11 +27,9 @@ pnpm add ape-im-sdk-react
|
|
|
27
27
|
## Requirements
|
|
28
28
|
|
|
29
29
|
- **React 18+**
|
|
30
|
-
- **
|
|
30
|
+
- **Glyph Wallet** - Ape IM requires [Glyph](https://useglyph.io) for wallet authentication
|
|
31
31
|
- Ape IM API endpoint (defaults to `https://www.apeinstantmessenger.com`)
|
|
32
32
|
|
|
33
|
-
> **Note:** The SDK currently requires MetaMask or a compatible injected wallet. WalletConnect support is planned for a future release.
|
|
34
|
-
|
|
35
33
|
## Quick Start
|
|
36
34
|
|
|
37
35
|
Add the chat widget to your app with just a few lines:
|
|
@@ -52,6 +50,27 @@ function App() {
|
|
|
52
50
|
|
|
53
51
|
That's it! Your users can now click the floating chat bubble to open the messenger.
|
|
54
52
|
|
|
53
|
+
## Next.js / SSR Support
|
|
54
|
+
|
|
55
|
+
The ChatWidget component is fully SSR-compatible and will only render on the client. For Next.js apps, you can use it directly:
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
// pages/_app.tsx or app/layout.tsx
|
|
59
|
+
import { ApeIMProvider, ChatWidget } from 'ape-im-sdk-react';
|
|
60
|
+
import 'ape-im-sdk-react/styles.css';
|
|
61
|
+
|
|
62
|
+
function MyApp({ Component, pageProps }) {
|
|
63
|
+
return (
|
|
64
|
+
<ApeIMProvider>
|
|
65
|
+
<Component {...pageProps} />
|
|
66
|
+
<ChatWidget position="bottom-right" />
|
|
67
|
+
</ApeIMProvider>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The widget automatically handles server-side rendering by returning `null` during SSR and hydrating properly on the client.
|
|
73
|
+
|
|
55
74
|
## Configuration
|
|
56
75
|
|
|
57
76
|
### ApeIMProvider Props
|
|
@@ -189,7 +208,7 @@ import type {
|
|
|
189
208
|
|
|
190
209
|
## API Documentation
|
|
191
210
|
|
|
192
|
-
For complete API documentation, visit: https://
|
|
211
|
+
For complete API documentation, visit: https://www.apeinstantmessenger.com/docs
|
|
193
212
|
|
|
194
213
|
## Publishing to npm
|
|
195
214
|
|
package/dist/index.d.mts
CHANGED
|
@@ -141,7 +141,7 @@ declare global {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
declare function ChatWidget({ position, offset, defaultOpen, bubbleSize, zIndex, }: ChatWidgetProps): react_jsx_runtime.JSX.Element;
|
|
144
|
+
declare function ChatWidget({ position, offset, defaultOpen, bubbleSize, zIndex, }: ChatWidgetProps): react_jsx_runtime.JSX.Element | null;
|
|
145
145
|
|
|
146
146
|
declare function useConversations(): ConversationsContextValue;
|
|
147
147
|
|
package/dist/index.d.ts
CHANGED
|
@@ -141,7 +141,7 @@ declare global {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
declare function ChatWidget({ position, offset, defaultOpen, bubbleSize, zIndex, }: ChatWidgetProps): react_jsx_runtime.JSX.Element;
|
|
144
|
+
declare function ChatWidget({ position, offset, defaultOpen, bubbleSize, zIndex, }: ChatWidgetProps): react_jsx_runtime.JSX.Element | null;
|
|
145
145
|
|
|
146
146
|
declare function useConversations(): ConversationsContextValue;
|
|
147
147
|
|
package/dist/index.js
CHANGED
|
@@ -76,14 +76,22 @@ function ApeIMProvider({
|
|
|
76
76
|
console.warn("Ape IM SDK: Cannot connect in SSR environment");
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
|
-
|
|
79
|
+
const ethereum = window.ethereum;
|
|
80
|
+
const isGlyph = ethereum?.isGlyph || ethereum?.providerMap?.get?.("glyph") || ethereum?.providers?.some?.((p) => p.isGlyph);
|
|
81
|
+
if (!ethereum) {
|
|
80
82
|
console.warn("Ape IM SDK: No wallet detected");
|
|
81
|
-
|
|
83
|
+
window.open("https://useglyph.io", "_blank");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (!isGlyph) {
|
|
87
|
+
console.warn("Ape IM SDK: Glyph wallet required");
|
|
88
|
+
alert("Ape IM requires Glyph wallet. Please install Glyph to use chat.");
|
|
89
|
+
window.open("https://useglyph.io", "_blank");
|
|
82
90
|
return;
|
|
83
91
|
}
|
|
84
92
|
setIsLoading(true);
|
|
85
93
|
try {
|
|
86
|
-
const accounts = await
|
|
94
|
+
const accounts = await ethereum.request({
|
|
87
95
|
method: "eth_requestAccounts"
|
|
88
96
|
});
|
|
89
97
|
if (!accounts || accounts.length === 0) {
|
|
@@ -359,13 +367,23 @@ function useChat(conversationId) {
|
|
|
359
367
|
|
|
360
368
|
// src/ChatWidget.tsx
|
|
361
369
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
362
|
-
var
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
370
|
+
var APE_LOGO_URL = "https://www.apeinstantmessenger.com/favicon.png";
|
|
371
|
+
var ApeIcon = ({ size = 32 }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
372
|
+
"img",
|
|
373
|
+
{
|
|
374
|
+
src: APE_LOGO_URL,
|
|
375
|
+
alt: "Ape IM",
|
|
376
|
+
width: size,
|
|
377
|
+
height: size,
|
|
378
|
+
style: {
|
|
379
|
+
width: size,
|
|
380
|
+
height: size,
|
|
381
|
+
objectFit: "contain",
|
|
382
|
+
borderRadius: "4px"
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
);
|
|
386
|
+
var isBrowser = typeof window !== "undefined";
|
|
369
387
|
function ChatWidget({
|
|
370
388
|
position = "bottom-right",
|
|
371
389
|
offset = { x: 20, y: 20 },
|
|
@@ -379,6 +397,10 @@ function ChatWidget({
|
|
|
379
397
|
const { messages, sendMessage, isTyping } = useChat(selectedConversation?.id || null);
|
|
380
398
|
const [messageInput, setMessageInput] = (0, import_react4.useState)("");
|
|
381
399
|
const [isOpen, setIsOpen] = (0, import_react4.useState)(defaultOpen);
|
|
400
|
+
const [isMounted, setIsMounted] = (0, import_react4.useState)(false);
|
|
401
|
+
(0, import_react4.useEffect)(() => {
|
|
402
|
+
setIsMounted(true);
|
|
403
|
+
}, []);
|
|
382
404
|
(0, import_react4.useEffect)(() => {
|
|
383
405
|
if (isWidgetOpen) setIsOpen(true);
|
|
384
406
|
}, [isWidgetOpen]);
|
|
@@ -391,7 +413,10 @@ function ChatWidget({
|
|
|
391
413
|
await sendMessage(messageInput);
|
|
392
414
|
setMessageInput("");
|
|
393
415
|
};
|
|
394
|
-
const isDark = theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
416
|
+
const isDark = theme === "dark" || theme === "system" && isBrowser && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
417
|
+
if (!isBrowser || !isMounted) {
|
|
418
|
+
return null;
|
|
419
|
+
}
|
|
395
420
|
const positionStyles = {
|
|
396
421
|
"bottom-right": { bottom: offset.y, right: offset.x },
|
|
397
422
|
"bottom-left": { bottom: offset.y, left: offset.x }
|
|
@@ -457,8 +482,8 @@ function ChatWidget({
|
|
|
457
482
|
}
|
|
458
483
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: containerStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: windowStyle, children: [
|
|
459
484
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: titleBarStyle, children: [
|
|
460
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", alignItems: "center", gap:
|
|
461
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ApeIcon, {}),
|
|
485
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
486
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ApeIcon, { size: 18 }),
|
|
462
487
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: "Ape Instant Messenger" })
|
|
463
488
|
] }),
|
|
464
489
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
@@ -493,7 +518,7 @@ function ChatWidget({
|
|
|
493
518
|
gap: 16,
|
|
494
519
|
background: isDark ? "#2a2a2a" : "#e0e0e0"
|
|
495
520
|
}, children: [
|
|
496
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ApeIcon, {}),
|
|
521
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ApeIcon, { size: 48 }),
|
|
497
522
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: {
|
|
498
523
|
textAlign: "center",
|
|
499
524
|
fontSize: 13,
|
package/dist/index.mjs
CHANGED
|
@@ -46,14 +46,22 @@ function ApeIMProvider({
|
|
|
46
46
|
console.warn("Ape IM SDK: Cannot connect in SSR environment");
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
|
-
|
|
49
|
+
const ethereum = window.ethereum;
|
|
50
|
+
const isGlyph = ethereum?.isGlyph || ethereum?.providerMap?.get?.("glyph") || ethereum?.providers?.some?.((p) => p.isGlyph);
|
|
51
|
+
if (!ethereum) {
|
|
50
52
|
console.warn("Ape IM SDK: No wallet detected");
|
|
51
|
-
|
|
53
|
+
window.open("https://useglyph.io", "_blank");
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (!isGlyph) {
|
|
57
|
+
console.warn("Ape IM SDK: Glyph wallet required");
|
|
58
|
+
alert("Ape IM requires Glyph wallet. Please install Glyph to use chat.");
|
|
59
|
+
window.open("https://useglyph.io", "_blank");
|
|
52
60
|
return;
|
|
53
61
|
}
|
|
54
62
|
setIsLoading(true);
|
|
55
63
|
try {
|
|
56
|
-
const accounts = await
|
|
64
|
+
const accounts = await ethereum.request({
|
|
57
65
|
method: "eth_requestAccounts"
|
|
58
66
|
});
|
|
59
67
|
if (!accounts || accounts.length === 0) {
|
|
@@ -329,13 +337,23 @@ function useChat(conversationId) {
|
|
|
329
337
|
|
|
330
338
|
// src/ChatWidget.tsx
|
|
331
339
|
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
332
|
-
var
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
340
|
+
var APE_LOGO_URL = "https://www.apeinstantmessenger.com/favicon.png";
|
|
341
|
+
var ApeIcon = ({ size = 32 }) => /* @__PURE__ */ jsx2(
|
|
342
|
+
"img",
|
|
343
|
+
{
|
|
344
|
+
src: APE_LOGO_URL,
|
|
345
|
+
alt: "Ape IM",
|
|
346
|
+
width: size,
|
|
347
|
+
height: size,
|
|
348
|
+
style: {
|
|
349
|
+
width: size,
|
|
350
|
+
height: size,
|
|
351
|
+
objectFit: "contain",
|
|
352
|
+
borderRadius: "4px"
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
);
|
|
356
|
+
var isBrowser = typeof window !== "undefined";
|
|
339
357
|
function ChatWidget({
|
|
340
358
|
position = "bottom-right",
|
|
341
359
|
offset = { x: 20, y: 20 },
|
|
@@ -349,6 +367,10 @@ function ChatWidget({
|
|
|
349
367
|
const { messages, sendMessage, isTyping } = useChat(selectedConversation?.id || null);
|
|
350
368
|
const [messageInput, setMessageInput] = useState4("");
|
|
351
369
|
const [isOpen, setIsOpen] = useState4(defaultOpen);
|
|
370
|
+
const [isMounted, setIsMounted] = useState4(false);
|
|
371
|
+
useEffect4(() => {
|
|
372
|
+
setIsMounted(true);
|
|
373
|
+
}, []);
|
|
352
374
|
useEffect4(() => {
|
|
353
375
|
if (isWidgetOpen) setIsOpen(true);
|
|
354
376
|
}, [isWidgetOpen]);
|
|
@@ -361,7 +383,10 @@ function ChatWidget({
|
|
|
361
383
|
await sendMessage(messageInput);
|
|
362
384
|
setMessageInput("");
|
|
363
385
|
};
|
|
364
|
-
const isDark = theme === "dark" || theme === "system" && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
386
|
+
const isDark = theme === "dark" || theme === "system" && isBrowser && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
387
|
+
if (!isBrowser || !isMounted) {
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
365
390
|
const positionStyles = {
|
|
366
391
|
"bottom-right": { bottom: offset.y, right: offset.x },
|
|
367
392
|
"bottom-left": { bottom: offset.y, left: offset.x }
|
|
@@ -427,8 +452,8 @@ function ChatWidget({
|
|
|
427
452
|
}
|
|
428
453
|
return /* @__PURE__ */ jsx2("div", { style: containerStyle, children: /* @__PURE__ */ jsxs("div", { style: windowStyle, children: [
|
|
429
454
|
/* @__PURE__ */ jsxs("div", { style: titleBarStyle, children: [
|
|
430
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap:
|
|
431
|
-
/* @__PURE__ */ jsx2(ApeIcon, {}),
|
|
455
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
456
|
+
/* @__PURE__ */ jsx2(ApeIcon, { size: 18 }),
|
|
432
457
|
/* @__PURE__ */ jsx2("span", { children: "Ape Instant Messenger" })
|
|
433
458
|
] }),
|
|
434
459
|
/* @__PURE__ */ jsx2(
|
|
@@ -463,7 +488,7 @@ function ChatWidget({
|
|
|
463
488
|
gap: 16,
|
|
464
489
|
background: isDark ? "#2a2a2a" : "#e0e0e0"
|
|
465
490
|
}, children: [
|
|
466
|
-
/* @__PURE__ */ jsx2(ApeIcon, {}),
|
|
491
|
+
/* @__PURE__ */ jsx2(ApeIcon, { size: 48 }),
|
|
467
492
|
/* @__PURE__ */ jsx2("p", { style: {
|
|
468
493
|
textAlign: "center",
|
|
469
494
|
fontSize: 13,
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ape-im-sdk-react",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "React SDK for Ape Instant Messenger - Add nostalgic AOL-style chat to your ApeChain dApp",
|
|
5
|
-
"main": "dist/index.
|
|
6
|
-
"module": "dist/index.
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"files": [
|
|
9
9
|
"dist",
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
],
|
|
12
12
|
"exports": {
|
|
13
13
|
".": {
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.mjs",
|
|
16
|
+
"require": "./dist/index.js"
|
|
17
17
|
},
|
|
18
18
|
"./styles.css": "./dist/styles.css"
|
|
19
19
|
},
|