@dubsdotapp/expo 0.5.22 → 0.5.23
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 +38 -3
- package/dist/index.d.ts +38 -3
- package/dist/index.js +67 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +65 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/chat/hooks.ts +44 -0
- package/src/chat/index.ts +3 -0
- package/src/chat/provider.tsx +33 -6
- package/src/chat/socket.ts +3 -0
- package/src/chat/types.ts +10 -0
- package/src/client.ts +10 -0
- package/src/index.ts +3 -0
package/package.json
CHANGED
package/src/chat/hooks.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
DirectMessage,
|
|
10
10
|
FriendUser,
|
|
11
11
|
FriendRequest,
|
|
12
|
+
SentFriendRequest,
|
|
12
13
|
SendMessageParams,
|
|
13
14
|
} from './types';
|
|
14
15
|
|
|
@@ -225,6 +226,49 @@ export function useFriendRequests(): {
|
|
|
225
226
|
return { requests: pendingRequests, loading, refetch };
|
|
226
227
|
}
|
|
227
228
|
|
|
229
|
+
/** Get pending friend requests this user has SENT (still awaiting response). */
|
|
230
|
+
export function useSentFriendRequests(): {
|
|
231
|
+
requests: SentFriendRequest[];
|
|
232
|
+
loading: boolean;
|
|
233
|
+
refetch: () => Promise<void>;
|
|
234
|
+
} {
|
|
235
|
+
const { sentFriendRequests, refreshSentFriendRequests } = useChatContext();
|
|
236
|
+
const [loading, setLoading] = useState(false);
|
|
237
|
+
|
|
238
|
+
const refetch = useCallback(async () => {
|
|
239
|
+
setLoading(true);
|
|
240
|
+
await refreshSentFriendRequests();
|
|
241
|
+
setLoading(false);
|
|
242
|
+
}, [refreshSentFriendRequests]);
|
|
243
|
+
|
|
244
|
+
return { requests: sentFriendRequests, loading, refetch };
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/** Cancel a pending friend request the current user previously sent. */
|
|
248
|
+
export function useCancelFriendRequest(): {
|
|
249
|
+
cancel: (requestId: number) => Promise<void>;
|
|
250
|
+
loading: boolean;
|
|
251
|
+
} {
|
|
252
|
+
const { client } = useDubs();
|
|
253
|
+
const { refreshSentFriendRequests } = useChatContext();
|
|
254
|
+
const [loading, setLoading] = useState(false);
|
|
255
|
+
|
|
256
|
+
const cancel = useCallback(
|
|
257
|
+
async (requestId: number) => {
|
|
258
|
+
setLoading(true);
|
|
259
|
+
try {
|
|
260
|
+
await client.cancelFriendRequest(requestId);
|
|
261
|
+
await refreshSentFriendRequests();
|
|
262
|
+
} finally {
|
|
263
|
+
setLoading(false);
|
|
264
|
+
}
|
|
265
|
+
},
|
|
266
|
+
[client, refreshSentFriendRequests],
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
return { cancel, loading };
|
|
270
|
+
}
|
|
271
|
+
|
|
228
272
|
/** Search for users by username */
|
|
229
273
|
export function useSearchUsers(): {
|
|
230
274
|
results: FriendUser[];
|
package/src/chat/index.ts
CHANGED
|
@@ -17,9 +17,11 @@ export {
|
|
|
17
17
|
useDirectMessages,
|
|
18
18
|
useFriends,
|
|
19
19
|
useFriendRequests,
|
|
20
|
+
useSentFriendRequests,
|
|
20
21
|
useSearchUsers,
|
|
21
22
|
useSendFriendRequest,
|
|
22
23
|
useRespondToFriendRequest,
|
|
24
|
+
useCancelFriendRequest,
|
|
23
25
|
} from './hooks';
|
|
24
26
|
|
|
25
27
|
// Types
|
|
@@ -31,6 +33,7 @@ export type {
|
|
|
31
33
|
Conversation,
|
|
32
34
|
FriendUser,
|
|
33
35
|
FriendRequest,
|
|
36
|
+
SentFriendRequest,
|
|
34
37
|
OnlineUser,
|
|
35
38
|
TypingEvent,
|
|
36
39
|
ChatNotification,
|
package/src/chat/provider.tsx
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
Conversation,
|
|
10
10
|
FriendUser,
|
|
11
11
|
FriendRequest,
|
|
12
|
+
SentFriendRequest,
|
|
12
13
|
DirectMessage,
|
|
13
14
|
ChatNotification,
|
|
14
15
|
} from './types';
|
|
@@ -30,16 +31,20 @@ export interface ChatContextValue {
|
|
|
30
31
|
conversations: Conversation[];
|
|
31
32
|
/** Friends list */
|
|
32
33
|
friends: FriendUser[];
|
|
33
|
-
/** Pending friend requests */
|
|
34
|
+
/** Pending friend requests (received) */
|
|
34
35
|
pendingRequests: FriendRequest[];
|
|
36
|
+
/** Pending friend requests this user has sent (still awaiting response) */
|
|
37
|
+
sentFriendRequests: SentFriendRequest[];
|
|
35
38
|
/** Reload messages from REST */
|
|
36
39
|
refreshMessages: () => Promise<void>;
|
|
37
40
|
/** Reload conversations from REST */
|
|
38
41
|
refreshConversations: () => Promise<void>;
|
|
39
42
|
/** Reload friends from REST */
|
|
40
43
|
refreshFriends: () => Promise<void>;
|
|
41
|
-
/** Reload pending friend requests from REST */
|
|
44
|
+
/** Reload pending friend requests (received) from REST */
|
|
42
45
|
refreshPendingRequests: () => Promise<void>;
|
|
46
|
+
/** Reload pending friend requests (sent) from REST */
|
|
47
|
+
refreshSentFriendRequests: () => Promise<void>;
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
const ChatContext = createContext<ChatContextValue | null>(null);
|
|
@@ -66,6 +71,7 @@ export function ChatProvider({ children, autoConnect = true }: ChatProviderProps
|
|
|
66
71
|
const [conversations, setConversations] = useState<Conversation[]>([]);
|
|
67
72
|
const [friends, setFriends] = useState<FriendUser[]>([]);
|
|
68
73
|
const [pendingRequests, setPendingRequests] = useState<FriendRequest[]>([]);
|
|
74
|
+
const [sentFriendRequests, setSentFriendRequests] = useState<SentFriendRequest[]>([]);
|
|
69
75
|
|
|
70
76
|
// ── REST loaders ──
|
|
71
77
|
|
|
@@ -106,6 +112,15 @@ export function ChatProvider({ children, autoConnect = true }: ChatProviderProps
|
|
|
106
112
|
}
|
|
107
113
|
}, [client]);
|
|
108
114
|
|
|
115
|
+
const refreshSentFriendRequests = useCallback(async () => {
|
|
116
|
+
try {
|
|
117
|
+
const res = await client.getSentFriendRequests();
|
|
118
|
+
setSentFriendRequests(res.requests);
|
|
119
|
+
} catch (_) {
|
|
120
|
+
// Server may not yet expose /social/friend-requests/sent — silent fail
|
|
121
|
+
}
|
|
122
|
+
}, [client]);
|
|
123
|
+
|
|
109
124
|
// ── Socket setup ──
|
|
110
125
|
|
|
111
126
|
useEffect(() => {
|
|
@@ -140,9 +155,18 @@ export function ChatProvider({ children, autoConnect = true }: ChatProviderProps
|
|
|
140
155
|
setUnreadCount((prev) => prev + 1);
|
|
141
156
|
// Refresh relevant lists on social notifications
|
|
142
157
|
if (n.type === 'friend_request') refreshPendingRequests();
|
|
143
|
-
if (n.type === 'friend_request_accepted')
|
|
158
|
+
if (n.type === 'friend_request_accepted') {
|
|
159
|
+
refreshFriends();
|
|
160
|
+
refreshSentFriendRequests();
|
|
161
|
+
}
|
|
162
|
+
if (n.type === 'friend_request_declined') refreshSentFriendRequests();
|
|
163
|
+
},
|
|
164
|
+
onFriendRequestAccepted: () => {
|
|
165
|
+
refreshFriends();
|
|
166
|
+
refreshSentFriendRequests();
|
|
144
167
|
},
|
|
145
|
-
|
|
168
|
+
onFriendRequestDeclined: () => refreshSentFriendRequests(),
|
|
169
|
+
onFriendRequestCancelled: () => refreshPendingRequests(),
|
|
146
170
|
onFriendRemoved: () => refreshFriends(),
|
|
147
171
|
});
|
|
148
172
|
|
|
@@ -152,11 +176,12 @@ export function ChatProvider({ children, autoConnect = true }: ChatProviderProps
|
|
|
152
176
|
refreshMessages();
|
|
153
177
|
refreshFriends().catch(() => {});
|
|
154
178
|
refreshPendingRequests().catch(() => {});
|
|
179
|
+
refreshSentFriendRequests().catch(() => {});
|
|
155
180
|
|
|
156
181
|
return () => {
|
|
157
182
|
chatSocket.disconnect();
|
|
158
183
|
};
|
|
159
|
-
}, [client, autoConnect, refreshMessages, refreshConversations, refreshFriends, refreshPendingRequests]);
|
|
184
|
+
}, [client, autoConnect, refreshMessages, refreshConversations, refreshFriends, refreshPendingRequests, refreshSentFriendRequests]);
|
|
160
185
|
|
|
161
186
|
// ── Reconnect on app foreground ──
|
|
162
187
|
|
|
@@ -192,12 +217,14 @@ export function ChatProvider({ children, autoConnect = true }: ChatProviderProps
|
|
|
192
217
|
conversations,
|
|
193
218
|
friends,
|
|
194
219
|
pendingRequests,
|
|
220
|
+
sentFriendRequests,
|
|
195
221
|
refreshMessages,
|
|
196
222
|
refreshConversations,
|
|
197
223
|
refreshFriends,
|
|
198
224
|
refreshPendingRequests,
|
|
225
|
+
refreshSentFriendRequests,
|
|
199
226
|
}),
|
|
200
|
-
[status, messages, onlineUsers, onlineCount, unreadCount, conversations, friends, pendingRequests, refreshMessages, refreshConversations, refreshFriends, refreshPendingRequests],
|
|
227
|
+
[status, messages, onlineUsers, onlineCount, unreadCount, conversations, friends, pendingRequests, sentFriendRequests, refreshMessages, refreshConversations, refreshFriends, refreshPendingRequests, refreshSentFriendRequests],
|
|
201
228
|
);
|
|
202
229
|
|
|
203
230
|
return <ChatContext.Provider value={value}>{children}</ChatContext.Provider>;
|
package/src/chat/socket.ts
CHANGED
|
@@ -36,6 +36,8 @@ export interface ChatSocketListeners {
|
|
|
36
36
|
// Social
|
|
37
37
|
onFriendRequestAccepted?: (data: { requestId: number; acceptedBy: number; acceptedByUsername: string }) => void;
|
|
38
38
|
onFriendRequestDeclined?: (data: { requestId: number; declinedBy: number }) => void;
|
|
39
|
+
/** Recipient-side: the original sender cancelled a pending friend request */
|
|
40
|
+
onFriendRequestCancelled?: (data: { requestId: number; cancelledBy: number }) => void;
|
|
39
41
|
onFriendRemoved?: (data: { removedBy: number }) => void;
|
|
40
42
|
// Errors
|
|
41
43
|
onError?: (error: { message: string }) => void;
|
|
@@ -108,6 +110,7 @@ export class ChatSocket {
|
|
|
108
110
|
// Social events
|
|
109
111
|
this.socket.on('friend_request_accepted', (data: any) => this.listeners.onFriendRequestAccepted?.(data));
|
|
110
112
|
this.socket.on('friend_request_declined', (data: any) => this.listeners.onFriendRequestDeclined?.(data));
|
|
113
|
+
this.socket.on('friend_request_cancelled', (data: any) => this.listeners.onFriendRequestCancelled?.(data));
|
|
111
114
|
this.socket.on('friend_removed', (data: any) => this.listeners.onFriendRemoved?.(data));
|
|
112
115
|
|
|
113
116
|
// Error
|
package/src/chat/types.ts
CHANGED
|
@@ -95,6 +95,16 @@ export interface FriendRequest {
|
|
|
95
95
|
createdAt: string;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
/** A friend request the current user has SENT (still pending). */
|
|
99
|
+
export interface SentFriendRequest {
|
|
100
|
+
id: number;
|
|
101
|
+
toUserId: number;
|
|
102
|
+
toUsername: string;
|
|
103
|
+
toAvatar: string | null;
|
|
104
|
+
toWallet: string;
|
|
105
|
+
createdAt: string;
|
|
106
|
+
}
|
|
107
|
+
|
|
98
108
|
// ── Online / Real-time Types ──
|
|
99
109
|
|
|
100
110
|
export interface OnlineUser {
|
package/src/client.ts
CHANGED
|
@@ -730,6 +730,16 @@ export class DubsClient {
|
|
|
730
730
|
return this.request('GET', '/social/friend-requests');
|
|
731
731
|
}
|
|
732
732
|
|
|
733
|
+
/** Get pending friend requests this user has sent (still awaiting response) */
|
|
734
|
+
async getSentFriendRequests(): Promise<{ requests: any[] }> {
|
|
735
|
+
return this.request('GET', '/social/friend-requests/sent');
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/** Cancel a pending friend request the user previously sent */
|
|
739
|
+
async cancelFriendRequest(requestId: number): Promise<void> {
|
|
740
|
+
await this.request('DELETE', `/social/friend-request/${requestId}`);
|
|
741
|
+
}
|
|
742
|
+
|
|
733
743
|
/** Accept a friend request */
|
|
734
744
|
async acceptFriendRequest(requestId: number): Promise<void> {
|
|
735
745
|
await this.request('POST', `/social/request/${requestId}/accept`);
|
package/src/index.ts
CHANGED
|
@@ -186,9 +186,11 @@ export {
|
|
|
186
186
|
useDirectMessages,
|
|
187
187
|
useFriends,
|
|
188
188
|
useFriendRequests,
|
|
189
|
+
useSentFriendRequests,
|
|
189
190
|
useSearchUsers,
|
|
190
191
|
useSendFriendRequest,
|
|
191
192
|
useRespondToFriendRequest,
|
|
193
|
+
useCancelFriendRequest,
|
|
192
194
|
} from './chat';
|
|
193
195
|
export type {
|
|
194
196
|
ChatProviderProps,
|
|
@@ -202,6 +204,7 @@ export type {
|
|
|
202
204
|
Conversation,
|
|
203
205
|
FriendUser,
|
|
204
206
|
FriendRequest,
|
|
207
|
+
SentFriendRequest,
|
|
205
208
|
OnlineUser,
|
|
206
209
|
TypingEvent,
|
|
207
210
|
ChatNotification,
|