This repository was archived by the owner on Nov 13, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 62
/
Copy pathuse-users.ts
83 lines (67 loc) · 2.42 KB
/
use-users.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import { useState, useEffect } from "react";
import { GetAllMetadataParameters, ObjectsEvent } from "pubnub";
import { usePubNub } from "pubnub-react";
import { merge, cloneDeep } from "lodash";
import { UserEntity } from "../types";
type HookReturnValue = [UserEntity[], () => void, number, Error];
export const useUsers = (options: GetAllMetadataParameters = {}): HookReturnValue => {
const pubnub = usePubNub();
const [users, setUsers] = useState<UserEntity[]>([]);
const [totalCount, setTotalCount] = useState(0);
const [page, setPage] = useState("");
const [error, setError] = useState<Error>();
const [doFetch, setDoFetch] = useState(true);
const paginatedOptions = merge({}, options, {
page: { next: page },
include: { totalCount: true },
}) as GetAllMetadataParameters;
const fetchMoreUsers = () => {
setDoFetch(true);
};
useEffect(() => {
let ignoreRequest = false;
if (doFetch) fetchPage();
async function fetchPage() {
try {
if (totalCount && users.length >= totalCount) return;
const response = await pubnub.objects.getAllUUIDMetadata(paginatedOptions);
if (ignoreRequest) return;
setDoFetch(false);
setUsers((users) => [...users, ...response.data]);
setTotalCount(response.totalCount || 0);
setPage(response.next || "");
} catch (e) {
setDoFetch(false);
setError(e as Error);
}
}
return () => {
ignoreRequest = true;
};
}, [doFetch, paginatedOptions, pubnub.objects, totalCount, users.length]);
useEffect(() => {
const listener = {
objects: (event: ObjectsEvent) => {
const message = event.message;
if (message.type !== "uuid") return;
setUsers((users) => {
const usersCopy = cloneDeep(users);
const user = usersCopy.find((u) => u.id === message.data.id);
// Set events are only handled for already fetched users in order to conform to filters and pagination
if (user && message.event === "set") {
Object.assign(user, message.data);
}
if (user && message.event === "delete") {
usersCopy.splice(usersCopy.indexOf(user), 1);
}
return usersCopy;
});
},
};
pubnub.addListener(listener);
return () => {
pubnub.removeListener(listener);
};
}, [pubnub]);
return [users, fetchMoreUsers, totalCount, error as Error];
};