ape-im-sdk-react 1.0.1 → 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 CHANGED
@@ -27,7 +27,7 @@ pnpm add ape-im-sdk-react
27
27
  ## Requirements
28
28
 
29
29
  - **React 18+**
30
- - **Web3 wallet** - Connect via Glyph or any injected wallet (MetaMask, Coinbase, etc.)
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
33
  ## Quick Start
@@ -50,6 +50,27 @@ function App() {
50
50
 
51
51
  That's it! Your users can now click the floating chat bubble to open the messenger.
52
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
+
53
74
  ## Configuration
54
75
 
55
76
  ### ApeIMProvider Props
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
- if (!window.ethereum) {
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
- alert("Please install MetaMask or another Web3 wallet to use chat.");
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 window.ethereum.request({
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 ApeIcon = () => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("svg", { viewBox: "0 0 40 40", width: "32", height: "32", fill: "none", children: [
363
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "20", cy: "20", r: "18", fill: "#1D3FE7" }),
364
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 22c0-4.4 3.6-8 8-8s8 3.6 8 8", stroke: "white", strokeWidth: "2", strokeLinecap: "round" }),
365
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "15", cy: "18", r: "2", fill: "white" }),
366
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "25", cy: "18", r: "2", fill: "white" }),
367
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M17 26c1.5 1.5 4.5 1.5 6 0", stroke: "white", strokeWidth: "2", strokeLinecap: "round" })
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: 8 }, children: [
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
- if (!window.ethereum) {
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
- alert("Please install MetaMask or another Web3 wallet to use chat.");
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 window.ethereum.request({
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 ApeIcon = () => /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 40 40", width: "32", height: "32", fill: "none", children: [
333
- /* @__PURE__ */ jsx2("circle", { cx: "20", cy: "20", r: "18", fill: "#1D3FE7" }),
334
- /* @__PURE__ */ jsx2("path", { d: "M12 22c0-4.4 3.6-8 8-8s8 3.6 8 8", stroke: "white", strokeWidth: "2", strokeLinecap: "round" }),
335
- /* @__PURE__ */ jsx2("circle", { cx: "15", cy: "18", r: "2", fill: "white" }),
336
- /* @__PURE__ */ jsx2("circle", { cx: "25", cy: "18", r: "2", fill: "white" }),
337
- /* @__PURE__ */ jsx2("path", { d: "M17 26c1.5 1.5 4.5 1.5 6 0", stroke: "white", strokeWidth: "2", strokeLinecap: "round" })
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: 8 }, children: [
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.1",
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.cjs.js",
6
- "module": "dist/index.esm.js",
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
- "import": "./dist/index.esm.js",
15
- "require": "./dist/index.cjs.js",
16
- "types": "./dist/index.d.ts"
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
  },