@anonfly/react 1.0.0 → 1.0.2
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/hooks/useAnonflyAuth.d.ts +17 -0
- package/dist/hooks/useAnonflyAuth.d.ts.map +1 -0
- package/dist/hooks/useAnonflyConversations.d.ts +17 -0
- package/dist/hooks/useAnonflyConversations.d.ts.map +1 -0
- package/dist/hooks/useAnonflyMessages.d.ts +16 -0
- package/dist/hooks/useAnonflyMessages.d.ts.map +1 -0
- package/dist/hooks/useAnonflyPresence.d.ts +9 -0
- package/dist/hooks/useAnonflyPresence.d.ts.map +1 -0
- package/dist/index.cjs +143 -127
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +143 -127
- package/package.json +11 -11
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AuthSession } from '@anonfly/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Headless hook for Anonfly Authentication.
|
|
4
|
+
* Handles login, session management, and premium status.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useAnonflyAuth(): {
|
|
7
|
+
session: AuthSession | null;
|
|
8
|
+
isAuthenticated: boolean;
|
|
9
|
+
loading: boolean;
|
|
10
|
+
error: Error | null;
|
|
11
|
+
login: (aid: string, username: string, challenge: string, signature: string, publicKey: string, exchangePublicKey: string) => Promise<AuthSession>;
|
|
12
|
+
logout: () => void;
|
|
13
|
+
getChallenge: (aid: string) => Promise<{
|
|
14
|
+
nonce: string;
|
|
15
|
+
}>;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=useAnonflyAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAnonflyAuth.d.ts","sourceRoot":"","sources":["../../src/hooks/useAnonflyAuth.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C;;;GAGG;AACH,wBAAgB,cAAc;;;;;iBAMY,MAAM,YAAY,MAAM,aAAa,MAAM,aAAa,MAAM,aAAa,MAAM,qBAAqB,MAAM;;wBA4BrG,MAAM;;;EAatD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Room } from '@anonfly/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Headless hook for browsing and managing Anonfly conversations (rooms).
|
|
4
|
+
*/
|
|
5
|
+
export declare function useAnonflyConversations(): {
|
|
6
|
+
rooms: Room[];
|
|
7
|
+
loading: boolean;
|
|
8
|
+
error: Error | null;
|
|
9
|
+
fetchRooms: (region?: string) => Promise<void>;
|
|
10
|
+
createRoom: (data: {
|
|
11
|
+
roomname: string;
|
|
12
|
+
isPrivate?: boolean;
|
|
13
|
+
description?: string;
|
|
14
|
+
password?: string;
|
|
15
|
+
}) => Promise<Room>;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=useAnonflyConversations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAnonflyConversations.d.ts","sourceRoot":"","sources":["../../src/hooks/useAnonflyConversations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC;;GAEG;AACH,wBAAgB,uBAAuB;;;;0BAMY,MAAM;uBAYT;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;EA0BjI"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Message } from '@anonfly/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Headless hook for managing Anonfly messages within a specific room.
|
|
4
|
+
* Supports fetching history and subscribing to real-time updates.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useAnonflyMessages(roomId?: string): {
|
|
7
|
+
messages: Message[];
|
|
8
|
+
loading: boolean;
|
|
9
|
+
error: Error | null;
|
|
10
|
+
fetchMessages: (options?: {
|
|
11
|
+
limit?: number;
|
|
12
|
+
before?: string;
|
|
13
|
+
}) => Promise<void>;
|
|
14
|
+
sendMessage: (content: string) => Promise<Message>;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=useAnonflyMessages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAnonflyMessages.d.ts","sourceRoot":"","sources":["../../src/hooks/useAnonflyMessages.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM;;;;8BAMK;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;2BAatC,MAAM;EA4BzD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAnonflyPresence.d.ts","sourceRoot":"","sources":["../../src/hooks/useAnonflyPresence.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM;;;;EAgCjD"}
|
package/dist/index.cjs
CHANGED
|
@@ -21,11 +21,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
AnonflyProvider: () => AnonflyProvider,
|
|
24
|
-
ChatInput: () => ChatInput,
|
|
25
|
-
MessageList: () => MessageList,
|
|
26
24
|
useAnonfly: () => useAnonfly,
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
useAnonflyAuth: () => useAnonflyAuth,
|
|
26
|
+
useAnonflyConversations: () => useAnonflyConversations,
|
|
27
|
+
useAnonflyMessages: () => useAnonflyMessages,
|
|
28
|
+
useAnonflyPresence: () => useAnonflyPresence
|
|
29
29
|
});
|
|
30
30
|
module.exports = __toCommonJS(index_exports);
|
|
31
31
|
|
|
@@ -46,158 +46,174 @@ var useAnonfly = () => {
|
|
|
46
46
|
return context.client;
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
// src/hooks/
|
|
49
|
+
// src/hooks/useAnonflyAuth.ts
|
|
50
50
|
var import_react2 = require("react");
|
|
51
|
-
|
|
51
|
+
function useAnonflyAuth() {
|
|
52
52
|
const client = useAnonfly();
|
|
53
|
-
const [
|
|
54
|
-
const [loading, setLoading] = (0, import_react2.useState)(
|
|
53
|
+
const [session, setSession] = (0, import_react2.useState)(null);
|
|
54
|
+
const [loading, setLoading] = (0, import_react2.useState)(false);
|
|
55
55
|
const [error, setError] = (0, import_react2.useState)(null);
|
|
56
|
-
const
|
|
56
|
+
const login = (0, import_react2.useCallback)(async (aid, username, challenge, signature, publicKey, exchangePublicKey) => {
|
|
57
|
+
setLoading(true);
|
|
58
|
+
setError(null);
|
|
57
59
|
try {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
const authSession = await client.auth.verify({
|
|
61
|
+
challenge,
|
|
62
|
+
signature,
|
|
63
|
+
identity: {
|
|
64
|
+
aid,
|
|
65
|
+
username,
|
|
66
|
+
publicKey,
|
|
67
|
+
exchangePublicKey
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
setSession(authSession);
|
|
71
|
+
return authSession;
|
|
61
72
|
} catch (err) {
|
|
62
73
|
setError(err);
|
|
74
|
+
throw err;
|
|
63
75
|
} finally {
|
|
64
76
|
setLoading(false);
|
|
65
77
|
}
|
|
66
|
-
};
|
|
67
|
-
(0, import_react2.useEffect)(() => {
|
|
68
|
-
fetchRooms();
|
|
69
78
|
}, [client]);
|
|
70
|
-
|
|
71
|
-
|
|
79
|
+
const logout = (0, import_react2.useCallback)(() => {
|
|
80
|
+
setSession(null);
|
|
81
|
+
}, []);
|
|
82
|
+
const getChallenge = (0, import_react2.useCallback)(async (aid) => {
|
|
83
|
+
return client.auth.generateChallenge(aid);
|
|
84
|
+
}, [client]);
|
|
85
|
+
return {
|
|
86
|
+
session,
|
|
87
|
+
isAuthenticated: !!session,
|
|
88
|
+
loading,
|
|
89
|
+
error,
|
|
90
|
+
login,
|
|
91
|
+
logout,
|
|
92
|
+
getChallenge
|
|
93
|
+
};
|
|
94
|
+
}
|
|
72
95
|
|
|
73
|
-
// src/hooks/
|
|
96
|
+
// src/hooks/useAnonflyMessages.ts
|
|
74
97
|
var import_react3 = require("react");
|
|
75
|
-
|
|
98
|
+
function useAnonflyMessages(roomId) {
|
|
76
99
|
const client = useAnonfly();
|
|
77
100
|
const [messages, setMessages] = (0, import_react3.useState)([]);
|
|
78
|
-
const [loading, setLoading] = (0, import_react3.useState)(
|
|
101
|
+
const [loading, setLoading] = (0, import_react3.useState)(false);
|
|
79
102
|
const [error, setError] = (0, import_react3.useState)(null);
|
|
103
|
+
const fetchMessages = (0, import_react3.useCallback)(async (options) => {
|
|
104
|
+
if (!roomId) return;
|
|
105
|
+
setLoading(true);
|
|
106
|
+
try {
|
|
107
|
+
const data = await client.messages.list(roomId, options);
|
|
108
|
+
setMessages(data);
|
|
109
|
+
} catch (err) {
|
|
110
|
+
setError(err);
|
|
111
|
+
} finally {
|
|
112
|
+
setLoading(false);
|
|
113
|
+
}
|
|
114
|
+
}, [client, roomId]);
|
|
115
|
+
const sendMessage = (0, import_react3.useCallback)(async (content) => {
|
|
116
|
+
if (!roomId) throw new Error("Room ID is required to send a message");
|
|
117
|
+
return client.messages.send(roomId, content);
|
|
118
|
+
}, [client, roomId]);
|
|
80
119
|
(0, import_react3.useEffect)(() => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
setMessages(data);
|
|
86
|
-
} catch (err) {
|
|
87
|
-
setError(err);
|
|
88
|
-
} finally {
|
|
89
|
-
setLoading(false);
|
|
120
|
+
if (!roomId || !client.ws) return;
|
|
121
|
+
const handler = (event) => {
|
|
122
|
+
if (event.type === "message" && event.data.roomId === roomId) {
|
|
123
|
+
setMessages((prev) => [...prev, event.data]);
|
|
90
124
|
}
|
|
91
125
|
};
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
}, [client, roomId]);
|
|
105
|
-
const sendMessage = async (content) => {
|
|
106
|
-
const newMessage = await client.messages.send(roomId, content);
|
|
107
|
-
return newMessage;
|
|
126
|
+
client.ws.on("message", handler);
|
|
127
|
+
return () => {
|
|
128
|
+
client.ws?.removeListener("message", handler);
|
|
129
|
+
};
|
|
130
|
+
}, [client.ws, roomId]);
|
|
131
|
+
return {
|
|
132
|
+
messages,
|
|
133
|
+
loading,
|
|
134
|
+
error,
|
|
135
|
+
fetchMessages,
|
|
136
|
+
sendMessage
|
|
108
137
|
};
|
|
109
|
-
return { messages, loading, error, sendMessage };
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
// src/components/MessageList.tsx
|
|
113
|
-
var import_clsx = require("clsx");
|
|
114
|
-
var import_tailwind_merge = require("tailwind-merge");
|
|
115
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
116
|
-
function cn(...inputs) {
|
|
117
|
-
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
118
138
|
}
|
|
119
|
-
var MessageList = ({ roomId, className }) => {
|
|
120
|
-
const { messages, loading, error } = useMessages(roomId);
|
|
121
|
-
if (loading && messages.length === 0) {
|
|
122
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "p-4 text-center opacity-50", children: "Loading messages..." });
|
|
123
|
-
}
|
|
124
|
-
if (error) {
|
|
125
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "p-4 text-center text-red-500", children: [
|
|
126
|
-
"Error: ",
|
|
127
|
-
error.message
|
|
128
|
-
] });
|
|
129
|
-
}
|
|
130
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: cn("flex flex-col gap-4 overflow-y-auto p-4", className), children: messages.map((msg) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
131
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
132
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-xs font-bold opacity-70", children: msg.senderId }),
|
|
133
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-[10px] opacity-40", children: new Date(msg.timestamp).toLocaleTimeString() })
|
|
134
|
-
] }),
|
|
135
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "rounded-lg bg-gray-100 p-3 text-sm dark:bg-zinc-800", children: msg.content })
|
|
136
|
-
] }, msg.id)) });
|
|
137
|
-
};
|
|
138
139
|
|
|
139
|
-
// src/
|
|
140
|
+
// src/hooks/useAnonflyConversations.ts
|
|
140
141
|
var import_react4 = require("react");
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
var ChatInput = ({ roomId, className, placeholder = "Type a message..." }) => {
|
|
149
|
-
const { sendMessage } = useMessages(roomId);
|
|
150
|
-
const [content, setContent] = (0, import_react4.useState)("");
|
|
151
|
-
const [sending, setSending] = (0, import_react4.useState)(false);
|
|
152
|
-
const handleSubmit = async (e) => {
|
|
153
|
-
e.preventDefault();
|
|
154
|
-
if (!content.trim() || sending) return;
|
|
142
|
+
function useAnonflyConversations() {
|
|
143
|
+
const client = useAnonfly();
|
|
144
|
+
const [rooms, setRooms] = (0, import_react4.useState)([]);
|
|
145
|
+
const [loading, setLoading] = (0, import_react4.useState)(false);
|
|
146
|
+
const [error, setError] = (0, import_react4.useState)(null);
|
|
147
|
+
const fetchRooms = (0, import_react4.useCallback)(async (region) => {
|
|
148
|
+
setLoading(true);
|
|
155
149
|
try {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
setContent("");
|
|
150
|
+
const data = await client.rooms.list(region);
|
|
151
|
+
setRooms(data);
|
|
159
152
|
} catch (err) {
|
|
160
|
-
|
|
153
|
+
setError(err);
|
|
161
154
|
} finally {
|
|
162
|
-
|
|
155
|
+
setLoading(false);
|
|
163
156
|
}
|
|
157
|
+
}, [client]);
|
|
158
|
+
const createRoom = (0, import_react4.useCallback)(async (data) => {
|
|
159
|
+
return client.rooms.create(data);
|
|
160
|
+
}, [client]);
|
|
161
|
+
(0, import_react4.useEffect)(() => {
|
|
162
|
+
let unsubscribe;
|
|
163
|
+
client.rooms.subscribeToPublicList((updatedRooms) => {
|
|
164
|
+
setRooms(updatedRooms);
|
|
165
|
+
}).then((unsub) => {
|
|
166
|
+
unsubscribe = unsub;
|
|
167
|
+
});
|
|
168
|
+
return () => {
|
|
169
|
+
if (unsubscribe) unsubscribe();
|
|
170
|
+
};
|
|
171
|
+
}, [client]);
|
|
172
|
+
return {
|
|
173
|
+
rooms,
|
|
174
|
+
loading,
|
|
175
|
+
error,
|
|
176
|
+
fetchRooms,
|
|
177
|
+
createRoom
|
|
164
178
|
};
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// src/hooks/useAnonflyPresence.ts
|
|
182
|
+
var import_react5 = require("react");
|
|
183
|
+
function useAnonflyPresence(roomId) {
|
|
184
|
+
const client = useAnonfly();
|
|
185
|
+
const [participants, setParticipants] = (0, import_react5.useState)([]);
|
|
186
|
+
const [loading, setLoading] = (0, import_react5.useState)(false);
|
|
187
|
+
const [error, setError] = (0, import_react5.useState)(null);
|
|
188
|
+
(0, import_react5.useEffect)(() => {
|
|
189
|
+
if (!roomId) return;
|
|
190
|
+
setLoading(true);
|
|
191
|
+
let unsubscribe;
|
|
192
|
+
client.rooms.subscribeToRoomDetails(roomId, (details) => {
|
|
193
|
+
setParticipants(details.participants);
|
|
194
|
+
setLoading(false);
|
|
195
|
+
}).then((unsub) => {
|
|
196
|
+
unsubscribe = unsub;
|
|
197
|
+
}).catch((err) => {
|
|
198
|
+
setError(err);
|
|
199
|
+
setLoading(false);
|
|
200
|
+
});
|
|
201
|
+
return () => {
|
|
202
|
+
if (unsubscribe) unsubscribe();
|
|
203
|
+
};
|
|
204
|
+
}, [client, roomId]);
|
|
205
|
+
return {
|
|
206
|
+
participants,
|
|
207
|
+
loading,
|
|
208
|
+
error
|
|
209
|
+
};
|
|
210
|
+
}
|
|
195
211
|
// Annotate the CommonJS export names for ESM import in node:
|
|
196
212
|
0 && (module.exports = {
|
|
197
213
|
AnonflyProvider,
|
|
198
|
-
ChatInput,
|
|
199
|
-
MessageList,
|
|
200
214
|
useAnonfly,
|
|
201
|
-
|
|
202
|
-
|
|
215
|
+
useAnonflyAuth,
|
|
216
|
+
useAnonflyConversations,
|
|
217
|
+
useAnonflyMessages,
|
|
218
|
+
useAnonflyPresence
|
|
203
219
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from './context/AnonflyContext
|
|
2
|
-
export * from './hooks/
|
|
3
|
-
export * from './hooks/
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
1
|
+
export * from './context/AnonflyContext';
|
|
2
|
+
export * from './hooks/useAnonflyAuth';
|
|
3
|
+
export * from './hooks/useAnonflyMessages';
|
|
4
|
+
export * from './hooks/useAnonflyConversations';
|
|
5
|
+
export * from './hooks/useAnonflyPresence';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iCAAiC,CAAC;AAChD,cAAc,4BAA4B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -15,157 +15,173 @@ var useAnonfly = () => {
|
|
|
15
15
|
return context.client;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
// src/hooks/
|
|
19
|
-
import {
|
|
20
|
-
|
|
18
|
+
// src/hooks/useAnonflyAuth.ts
|
|
19
|
+
import { useState, useCallback } from "react";
|
|
20
|
+
function useAnonflyAuth() {
|
|
21
21
|
const client = useAnonfly();
|
|
22
|
-
const [
|
|
23
|
-
const [loading, setLoading] = useState(
|
|
22
|
+
const [session, setSession] = useState(null);
|
|
23
|
+
const [loading, setLoading] = useState(false);
|
|
24
24
|
const [error, setError] = useState(null);
|
|
25
|
-
const
|
|
25
|
+
const login = useCallback(async (aid, username, challenge, signature, publicKey, exchangePublicKey) => {
|
|
26
|
+
setLoading(true);
|
|
27
|
+
setError(null);
|
|
26
28
|
try {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
const authSession = await client.auth.verify({
|
|
30
|
+
challenge,
|
|
31
|
+
signature,
|
|
32
|
+
identity: {
|
|
33
|
+
aid,
|
|
34
|
+
username,
|
|
35
|
+
publicKey,
|
|
36
|
+
exchangePublicKey
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
setSession(authSession);
|
|
40
|
+
return authSession;
|
|
30
41
|
} catch (err) {
|
|
31
42
|
setError(err);
|
|
43
|
+
throw err;
|
|
32
44
|
} finally {
|
|
33
45
|
setLoading(false);
|
|
34
46
|
}
|
|
35
|
-
};
|
|
36
|
-
useEffect(() => {
|
|
37
|
-
fetchRooms();
|
|
38
47
|
}, [client]);
|
|
39
|
-
|
|
40
|
-
|
|
48
|
+
const logout = useCallback(() => {
|
|
49
|
+
setSession(null);
|
|
50
|
+
}, []);
|
|
51
|
+
const getChallenge = useCallback(async (aid) => {
|
|
52
|
+
return client.auth.generateChallenge(aid);
|
|
53
|
+
}, [client]);
|
|
54
|
+
return {
|
|
55
|
+
session,
|
|
56
|
+
isAuthenticated: !!session,
|
|
57
|
+
loading,
|
|
58
|
+
error,
|
|
59
|
+
login,
|
|
60
|
+
logout,
|
|
61
|
+
getChallenge
|
|
62
|
+
};
|
|
63
|
+
}
|
|
41
64
|
|
|
42
|
-
// src/hooks/
|
|
43
|
-
import {
|
|
44
|
-
|
|
65
|
+
// src/hooks/useAnonflyMessages.ts
|
|
66
|
+
import { useState as useState2, useCallback as useCallback2, useEffect } from "react";
|
|
67
|
+
function useAnonflyMessages(roomId) {
|
|
45
68
|
const client = useAnonfly();
|
|
46
69
|
const [messages, setMessages] = useState2([]);
|
|
47
|
-
const [loading, setLoading] = useState2(
|
|
70
|
+
const [loading, setLoading] = useState2(false);
|
|
48
71
|
const [error, setError] = useState2(null);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
fetchMessages();
|
|
62
|
-
if (client.ws) {
|
|
63
|
-
const handleMessage = (msg) => {
|
|
64
|
-
if (msg.roomId === roomId) {
|
|
65
|
-
setMessages((prev) => [...prev, msg]);
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
client.ws.on("message", handleMessage);
|
|
69
|
-
return () => {
|
|
70
|
-
client.ws?.off("message", handleMessage);
|
|
71
|
-
};
|
|
72
|
+
const fetchMessages = useCallback2(async (options) => {
|
|
73
|
+
if (!roomId) return;
|
|
74
|
+
setLoading(true);
|
|
75
|
+
try {
|
|
76
|
+
const data = await client.messages.list(roomId, options);
|
|
77
|
+
setMessages(data);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
setError(err);
|
|
80
|
+
} finally {
|
|
81
|
+
setLoading(false);
|
|
72
82
|
}
|
|
73
83
|
}, [client, roomId]);
|
|
74
|
-
const sendMessage = async (content) => {
|
|
75
|
-
|
|
76
|
-
return
|
|
84
|
+
const sendMessage = useCallback2(async (content) => {
|
|
85
|
+
if (!roomId) throw new Error("Room ID is required to send a message");
|
|
86
|
+
return client.messages.send(roomId, content);
|
|
87
|
+
}, [client, roomId]);
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (!roomId || !client.ws) return;
|
|
90
|
+
const handler = (event) => {
|
|
91
|
+
if (event.type === "message" && event.data.roomId === roomId) {
|
|
92
|
+
setMessages((prev) => [...prev, event.data]);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
client.ws.on("message", handler);
|
|
96
|
+
return () => {
|
|
97
|
+
client.ws?.removeListener("message", handler);
|
|
98
|
+
};
|
|
99
|
+
}, [client.ws, roomId]);
|
|
100
|
+
return {
|
|
101
|
+
messages,
|
|
102
|
+
loading,
|
|
103
|
+
error,
|
|
104
|
+
fetchMessages,
|
|
105
|
+
sendMessage
|
|
77
106
|
};
|
|
78
|
-
return { messages, loading, error, sendMessage };
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
// src/components/MessageList.tsx
|
|
82
|
-
import { clsx } from "clsx";
|
|
83
|
-
import { twMerge } from "tailwind-merge";
|
|
84
|
-
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
85
|
-
function cn(...inputs) {
|
|
86
|
-
return twMerge(clsx(inputs));
|
|
87
107
|
}
|
|
88
|
-
var MessageList = ({ roomId, className }) => {
|
|
89
|
-
const { messages, loading, error } = useMessages(roomId);
|
|
90
|
-
if (loading && messages.length === 0) {
|
|
91
|
-
return /* @__PURE__ */ jsx2("div", { className: "p-4 text-center opacity-50", children: "Loading messages..." });
|
|
92
|
-
}
|
|
93
|
-
if (error) {
|
|
94
|
-
return /* @__PURE__ */ jsxs("div", { className: "p-4 text-center text-red-500", children: [
|
|
95
|
-
"Error: ",
|
|
96
|
-
error.message
|
|
97
|
-
] });
|
|
98
|
-
}
|
|
99
|
-
return /* @__PURE__ */ jsx2("div", { className: cn("flex flex-col gap-4 overflow-y-auto p-4", className), children: messages.map((msg) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
100
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
101
|
-
/* @__PURE__ */ jsx2("span", { className: "text-xs font-bold opacity-70", children: msg.senderId }),
|
|
102
|
-
/* @__PURE__ */ jsx2("span", { className: "text-[10px] opacity-40", children: new Date(msg.timestamp).toLocaleTimeString() })
|
|
103
|
-
] }),
|
|
104
|
-
/* @__PURE__ */ jsx2("div", { className: "rounded-lg bg-gray-100 p-3 text-sm dark:bg-zinc-800", children: msg.content })
|
|
105
|
-
] }, msg.id)) });
|
|
106
|
-
};
|
|
107
108
|
|
|
108
|
-
// src/
|
|
109
|
-
import { useState as useState3 } from "react";
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
var ChatInput = ({ roomId, className, placeholder = "Type a message..." }) => {
|
|
118
|
-
const { sendMessage } = useMessages(roomId);
|
|
119
|
-
const [content, setContent] = useState3("");
|
|
120
|
-
const [sending, setSending] = useState3(false);
|
|
121
|
-
const handleSubmit = async (e) => {
|
|
122
|
-
e.preventDefault();
|
|
123
|
-
if (!content.trim() || sending) return;
|
|
109
|
+
// src/hooks/useAnonflyConversations.ts
|
|
110
|
+
import { useState as useState3, useCallback as useCallback3, useEffect as useEffect2 } from "react";
|
|
111
|
+
function useAnonflyConversations() {
|
|
112
|
+
const client = useAnonfly();
|
|
113
|
+
const [rooms, setRooms] = useState3([]);
|
|
114
|
+
const [loading, setLoading] = useState3(false);
|
|
115
|
+
const [error, setError] = useState3(null);
|
|
116
|
+
const fetchRooms = useCallback3(async (region) => {
|
|
117
|
+
setLoading(true);
|
|
124
118
|
try {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
setContent("");
|
|
119
|
+
const data = await client.rooms.list(region);
|
|
120
|
+
setRooms(data);
|
|
128
121
|
} catch (err) {
|
|
129
|
-
|
|
122
|
+
setError(err);
|
|
130
123
|
} finally {
|
|
131
|
-
|
|
124
|
+
setLoading(false);
|
|
132
125
|
}
|
|
126
|
+
}, [client]);
|
|
127
|
+
const createRoom = useCallback3(async (data) => {
|
|
128
|
+
return client.rooms.create(data);
|
|
129
|
+
}, [client]);
|
|
130
|
+
useEffect2(() => {
|
|
131
|
+
let unsubscribe;
|
|
132
|
+
client.rooms.subscribeToPublicList((updatedRooms) => {
|
|
133
|
+
setRooms(updatedRooms);
|
|
134
|
+
}).then((unsub) => {
|
|
135
|
+
unsubscribe = unsub;
|
|
136
|
+
});
|
|
137
|
+
return () => {
|
|
138
|
+
if (unsubscribe) unsubscribe();
|
|
139
|
+
};
|
|
140
|
+
}, [client]);
|
|
141
|
+
return {
|
|
142
|
+
rooms,
|
|
143
|
+
loading,
|
|
144
|
+
error,
|
|
145
|
+
fetchRooms,
|
|
146
|
+
createRoom
|
|
133
147
|
};
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/hooks/useAnonflyPresence.ts
|
|
151
|
+
import { useState as useState4, useEffect as useEffect3 } from "react";
|
|
152
|
+
function useAnonflyPresence(roomId) {
|
|
153
|
+
const client = useAnonfly();
|
|
154
|
+
const [participants, setParticipants] = useState4([]);
|
|
155
|
+
const [loading, setLoading] = useState4(false);
|
|
156
|
+
const [error, setError] = useState4(null);
|
|
157
|
+
useEffect3(() => {
|
|
158
|
+
if (!roomId) return;
|
|
159
|
+
setLoading(true);
|
|
160
|
+
let unsubscribe;
|
|
161
|
+
client.rooms.subscribeToRoomDetails(roomId, (details) => {
|
|
162
|
+
setParticipants(details.participants);
|
|
163
|
+
setLoading(false);
|
|
164
|
+
}).then((unsub) => {
|
|
165
|
+
unsubscribe = unsub;
|
|
166
|
+
}).catch((err) => {
|
|
167
|
+
setError(err);
|
|
168
|
+
setLoading(false);
|
|
169
|
+
});
|
|
170
|
+
return () => {
|
|
171
|
+
if (unsubscribe) unsubscribe();
|
|
172
|
+
};
|
|
173
|
+
}, [client, roomId]);
|
|
174
|
+
return {
|
|
175
|
+
participants,
|
|
176
|
+
loading,
|
|
177
|
+
error
|
|
178
|
+
};
|
|
179
|
+
}
|
|
164
180
|
export {
|
|
165
181
|
AnonflyProvider,
|
|
166
|
-
ChatInput,
|
|
167
|
-
MessageList,
|
|
168
182
|
useAnonfly,
|
|
169
|
-
|
|
170
|
-
|
|
183
|
+
useAnonflyAuth,
|
|
184
|
+
useAnonflyConversations,
|
|
185
|
+
useAnonflyMessages,
|
|
186
|
+
useAnonflyPresence
|
|
171
187
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@anonfly/react",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "React UI components for Anonfly SDK",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -17,22 +17,22 @@
|
|
|
17
17
|
"dev": "tsup src/index.ts --format cjs,esm --watch --dts --external react"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@anonfly/sdk": "
|
|
21
|
-
"lucide-react": "^0.
|
|
22
|
-
"clsx": "^2.1.
|
|
23
|
-
"tailwind-merge": "^
|
|
20
|
+
"@anonfly/sdk": "^1.0.1",
|
|
21
|
+
"lucide-react": "^0.473.0",
|
|
22
|
+
"clsx": "^2.1.1",
|
|
23
|
+
"tailwind-merge": "^3.0.1"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"react": ">=18",
|
|
27
27
|
"react-dom": ">=18"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@types/react": "^
|
|
31
|
-
"@types/react-dom": "^
|
|
32
|
-
"react": "^
|
|
33
|
-
"react-dom": "^
|
|
34
|
-
"tsup": "^8.
|
|
35
|
-
"typescript": "^5.
|
|
30
|
+
"@types/react": "^19.0.0",
|
|
31
|
+
"@types/react-dom": "^19.0.0",
|
|
32
|
+
"react": "^19.0.0",
|
|
33
|
+
"react-dom": "^19.0.0",
|
|
34
|
+
"tsup": "^8.3.5",
|
|
35
|
+
"typescript": "^5.7.2"
|
|
36
36
|
},
|
|
37
37
|
"publishConfig": {
|
|
38
38
|
"access": "public"
|