@liveblocks/react 1.10.0-beta2 → 1.10.0-beta4
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 +11 -7
- package/dist/index.d.ts +11 -7
- package/dist/index.js +553 -431
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +546 -424
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { detectDupes } from "@liveblocks/core";
|
|
|
5
5
|
|
|
6
6
|
// src/version.ts
|
|
7
7
|
var PKG_NAME = "@liveblocks/react";
|
|
8
|
-
var PKG_VERSION = "1.10.0-
|
|
8
|
+
var PKG_VERSION = "1.10.0-beta4";
|
|
9
9
|
var PKG_FORMAT = "esm";
|
|
10
10
|
|
|
11
11
|
// src/ClientSideSuspense.tsx
|
|
@@ -34,7 +34,10 @@ import { useSyncExternalStoreWithSelector as useSyncExternalStoreWithSelector2 }
|
|
|
34
34
|
import { applyOptimisticUpdates } from "@liveblocks/core";
|
|
35
35
|
function selectedInboxNotifications(state) {
|
|
36
36
|
const result = applyOptimisticUpdates(state);
|
|
37
|
-
return Object.values(result.inboxNotifications)
|
|
37
|
+
return Object.values(result.inboxNotifications).sort(
|
|
38
|
+
// Sort so that the most recent notifications are first
|
|
39
|
+
(a, b) => b.notifiedAt.getTime() - a.notifiedAt.getTime()
|
|
40
|
+
);
|
|
38
41
|
}
|
|
39
42
|
|
|
40
43
|
// src/shared.ts
|
|
@@ -45,8 +48,10 @@ import { useSyncExternalStore as useSyncExternalStore2 } from "use-sync-external
|
|
|
45
48
|
// src/room.tsx
|
|
46
49
|
import { shallow } from "@liveblocks/client";
|
|
47
50
|
import {
|
|
51
|
+
addReaction,
|
|
48
52
|
CommentsApiError,
|
|
49
53
|
console as console2,
|
|
54
|
+
deleteComment,
|
|
50
55
|
deprecateIf,
|
|
51
56
|
errorIf,
|
|
52
57
|
isLiveNode,
|
|
@@ -54,8 +59,10 @@ import {
|
|
|
54
59
|
makeEventSource,
|
|
55
60
|
makePoller,
|
|
56
61
|
NotificationsApiError,
|
|
62
|
+
removeReaction,
|
|
57
63
|
ServerMsgCode,
|
|
58
|
-
stringify
|
|
64
|
+
stringify,
|
|
65
|
+
upsertComment
|
|
59
66
|
} from "@liveblocks/core";
|
|
60
67
|
import { nanoid as nanoid2 } from "nanoid";
|
|
61
68
|
import * as React2 from "react";
|
|
@@ -151,11 +158,12 @@ function createCommentId() {
|
|
|
151
158
|
|
|
152
159
|
// src/comments/lib/select-notification-settings.ts
|
|
153
160
|
import {
|
|
154
|
-
applyOptimisticUpdates as applyOptimisticUpdates2
|
|
161
|
+
applyOptimisticUpdates as applyOptimisticUpdates2,
|
|
162
|
+
nn
|
|
155
163
|
} from "@liveblocks/core";
|
|
156
164
|
function selectNotificationSettings(roomId, state) {
|
|
157
165
|
const { notificationSettings } = applyOptimisticUpdates2(state);
|
|
158
|
-
return notificationSettings[roomId];
|
|
166
|
+
return nn(notificationSettings[roomId]);
|
|
159
167
|
}
|
|
160
168
|
|
|
161
169
|
// src/comments/lib/selected-threads.ts
|
|
@@ -167,6 +175,9 @@ function selectedThreads(roomId, state, options) {
|
|
|
167
175
|
const threads = Object.values(result.threads).filter((thread) => {
|
|
168
176
|
if (thread.roomId !== roomId)
|
|
169
177
|
return false;
|
|
178
|
+
if (thread.deletedAt !== void 0) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
170
181
|
const query = options.query;
|
|
171
182
|
if (!query)
|
|
172
183
|
return true;
|
|
@@ -180,34 +191,6 @@ function selectedThreads(roomId, state, options) {
|
|
|
180
191
|
return threads.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
|
181
192
|
}
|
|
182
193
|
|
|
183
|
-
// src/comments/lib/upsert-comment.ts
|
|
184
|
-
function upsertComment(threads, newComment) {
|
|
185
|
-
const thread = threads[newComment.threadId];
|
|
186
|
-
if (thread === void 0) {
|
|
187
|
-
return threads;
|
|
188
|
-
}
|
|
189
|
-
const newComments = [];
|
|
190
|
-
let updated = false;
|
|
191
|
-
for (const comment of thread.comments) {
|
|
192
|
-
if (comment.id === newComment.id) {
|
|
193
|
-
updated = true;
|
|
194
|
-
newComments.push(newComment);
|
|
195
|
-
} else {
|
|
196
|
-
newComments.push(comment);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
if (!updated) {
|
|
200
|
-
newComments.push(newComment);
|
|
201
|
-
}
|
|
202
|
-
return {
|
|
203
|
-
...threads,
|
|
204
|
-
[thread.id]: {
|
|
205
|
-
...thread,
|
|
206
|
-
comments: newComments
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
|
|
211
194
|
// src/lib/use-initial.ts
|
|
212
195
|
import { useState as useState2 } from "react";
|
|
213
196
|
function useInitial(value) {
|
|
@@ -376,7 +359,9 @@ function createRoomContext(client, options) {
|
|
|
376
359
|
);
|
|
377
360
|
React2.useEffect(() => {
|
|
378
361
|
async function handleCommentEvent(message) {
|
|
379
|
-
const info = await room.getThread({
|
|
362
|
+
const info = await room[kInternal].comments.getThread({
|
|
363
|
+
threadId: message.threadId
|
|
364
|
+
});
|
|
380
365
|
if (!info) {
|
|
381
366
|
store.deleteThread(message.threadId);
|
|
382
367
|
return;
|
|
@@ -404,6 +389,9 @@ function createRoomContext(client, options) {
|
|
|
404
389
|
(message) => void handleCommentEvent(message)
|
|
405
390
|
);
|
|
406
391
|
}, [room]);
|
|
392
|
+
React2.useEffect(() => {
|
|
393
|
+
void getThreadsUpdates(room.id);
|
|
394
|
+
}, [room.id]);
|
|
407
395
|
React2.useEffect(() => {
|
|
408
396
|
const pair = stableEnterRoom(roomId, frozenProps);
|
|
409
397
|
setRoomLeavePair(pair);
|
|
@@ -786,15 +774,46 @@ function createRoomContext(client, options) {
|
|
|
786
774
|
const requestsCache = /* @__PURE__ */ new Map();
|
|
787
775
|
const poller = makePoller(refreshThreadsAndNotifications);
|
|
788
776
|
async function refreshThreadsAndNotifications() {
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
777
|
+
const requests = [];
|
|
778
|
+
client[kInternal].getRoomIds().map((roomId) => {
|
|
779
|
+
const room = client.getRoom(roomId);
|
|
780
|
+
if (room === null)
|
|
781
|
+
return;
|
|
782
|
+
const notificationSettingsQuery = makeNotificationSettingsQueryKey(
|
|
783
|
+
room.id
|
|
784
|
+
);
|
|
785
|
+
if (requestsCache.has(notificationSettingsQuery)) {
|
|
786
|
+
requests.push(
|
|
787
|
+
room[kInternal].notifications.getRoomNotificationSettings().then((settings) => {
|
|
788
|
+
store.updateRoomInboxNotificationSettings(
|
|
789
|
+
room.id,
|
|
790
|
+
settings,
|
|
791
|
+
notificationSettingsQuery
|
|
792
|
+
);
|
|
793
|
+
}).catch(() => {
|
|
794
|
+
})
|
|
795
795
|
);
|
|
796
|
-
}
|
|
797
|
-
|
|
796
|
+
}
|
|
797
|
+
const lastRequestedAt = lastRequestedAtByRoom.get(room.id);
|
|
798
|
+
if (lastRequestedAt === void 0)
|
|
799
|
+
return;
|
|
800
|
+
requests.push(
|
|
801
|
+
room[kInternal].comments.getThreads({ since: lastRequestedAt }).then((result) => {
|
|
802
|
+
store.updateThreadsAndNotifications(
|
|
803
|
+
result.threads,
|
|
804
|
+
result.inboxNotifications,
|
|
805
|
+
result.deletedThreads,
|
|
806
|
+
result.deletedInboxNotifications
|
|
807
|
+
);
|
|
808
|
+
const room2 = client.getRoom(roomId);
|
|
809
|
+
if (room2 === null)
|
|
810
|
+
return;
|
|
811
|
+
lastRequestedAtByRoom.set(room2.id, result.meta.requestedAt);
|
|
812
|
+
}).catch(() => {
|
|
813
|
+
})
|
|
814
|
+
);
|
|
815
|
+
});
|
|
816
|
+
await Promise.allSettled(requests);
|
|
798
817
|
}
|
|
799
818
|
function incrementQuerySubscribers(queryKey) {
|
|
800
819
|
const requestCache = requestsCache.get(queryKey);
|
|
@@ -824,16 +843,14 @@ function createRoomContext(client, options) {
|
|
|
824
843
|
poller.stop();
|
|
825
844
|
}
|
|
826
845
|
}
|
|
827
|
-
async function
|
|
846
|
+
async function getThreadsAndInboxNotifications(room, queryKey, options2) {
|
|
828
847
|
const requestInfo = requestsCache.get(queryKey);
|
|
829
848
|
if (requestInfo !== void 0) {
|
|
830
849
|
return requestInfo.promise;
|
|
831
850
|
}
|
|
832
|
-
const promise =
|
|
851
|
+
const promise = room[kInternal].comments.getThreads(options2);
|
|
833
852
|
requestsCache.set(queryKey, {
|
|
834
853
|
promise,
|
|
835
|
-
requestFactory,
|
|
836
|
-
onSuccess,
|
|
837
854
|
subscribers: 0
|
|
838
855
|
});
|
|
839
856
|
store.setQueryState(queryKey, {
|
|
@@ -841,36 +858,53 @@ function createRoomContext(client, options) {
|
|
|
841
858
|
});
|
|
842
859
|
try {
|
|
843
860
|
const result = await promise;
|
|
844
|
-
|
|
845
|
-
|
|
861
|
+
store.updateThreadsAndNotifications(
|
|
862
|
+
result.threads,
|
|
863
|
+
result.inboxNotifications,
|
|
864
|
+
result.deletedThreads,
|
|
865
|
+
result.deletedInboxNotifications,
|
|
866
|
+
queryKey
|
|
867
|
+
);
|
|
868
|
+
const lastRequestedAt = lastRequestedAtByRoom.get(room.id);
|
|
869
|
+
if (lastRequestedAt === void 0 || lastRequestedAt > result.meta.requestedAt) {
|
|
870
|
+
lastRequestedAtByRoom.set(room.id, result.meta.requestedAt);
|
|
871
|
+
}
|
|
872
|
+
} catch (err) {
|
|
846
873
|
store.setQueryState(queryKey, {
|
|
847
874
|
isLoading: false,
|
|
848
|
-
error:
|
|
875
|
+
error: err
|
|
849
876
|
});
|
|
850
877
|
}
|
|
851
878
|
poller.start(POLLING_INTERVAL);
|
|
852
879
|
}
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
880
|
+
const DEFAULT_DEDUPING_INTERVAL = 2e3;
|
|
881
|
+
const lastRequestedAtByRoom = /* @__PURE__ */ new Map();
|
|
882
|
+
let isFetchingThreadsUpdates = false;
|
|
883
|
+
async function getThreadsUpdates(roomId) {
|
|
884
|
+
const room = client.getRoom(roomId);
|
|
885
|
+
if (room === null)
|
|
886
|
+
return;
|
|
887
|
+
const since = lastRequestedAtByRoom.get(room.id);
|
|
888
|
+
if (since === void 0)
|
|
889
|
+
return;
|
|
890
|
+
if (isFetchingThreadsUpdates)
|
|
891
|
+
return;
|
|
892
|
+
try {
|
|
893
|
+
isFetchingThreadsUpdates = true;
|
|
894
|
+
const updates = await room[kInternal].comments.getThreads({ since });
|
|
895
|
+
setTimeout(() => {
|
|
896
|
+
isFetchingThreadsUpdates = false;
|
|
897
|
+
}, DEFAULT_DEDUPING_INTERVAL);
|
|
898
|
+
store.updateThreadsAndNotifications(
|
|
899
|
+
updates.threads,
|
|
900
|
+
updates.inboxNotifications,
|
|
901
|
+
updates.deletedThreads,
|
|
902
|
+
updates.deletedInboxNotifications
|
|
903
|
+
);
|
|
904
|
+
lastRequestedAtByRoom.set(room.id, updates.meta.requestedAt);
|
|
905
|
+
} catch (err) {
|
|
906
|
+
isFetchingThreadsUpdates = false;
|
|
907
|
+
}
|
|
874
908
|
}
|
|
875
909
|
function useThreads(options2 = { query: { metadata: {} } }) {
|
|
876
910
|
const room = useRoom();
|
|
@@ -885,7 +919,8 @@ function createRoomContext(client, options) {
|
|
|
885
919
|
}, [room, queryKey]);
|
|
886
920
|
const selector = React2.useCallback(
|
|
887
921
|
(state) => {
|
|
888
|
-
|
|
922
|
+
const query = state.queries[queryKey];
|
|
923
|
+
if (query === void 0 || query.isLoading) {
|
|
889
924
|
return {
|
|
890
925
|
isLoading: true
|
|
891
926
|
};
|
|
@@ -893,7 +928,7 @@ function createRoomContext(client, options) {
|
|
|
893
928
|
return {
|
|
894
929
|
threads: selectedThreads(room.id, state, options2),
|
|
895
930
|
isLoading: false,
|
|
896
|
-
error:
|
|
931
|
+
error: query.error
|
|
897
932
|
};
|
|
898
933
|
},
|
|
899
934
|
[room, queryKey]
|
|
@@ -934,7 +969,7 @@ function createRoomContext(client, options) {
|
|
|
934
969
|
return () => {
|
|
935
970
|
decrementQuerySubscribers(queryKey);
|
|
936
971
|
};
|
|
937
|
-
}, [
|
|
972
|
+
}, [queryKey]);
|
|
938
973
|
return useSyncExternalStoreWithSelector(
|
|
939
974
|
store.subscribe,
|
|
940
975
|
store.get,
|
|
@@ -950,12 +985,12 @@ function createRoomContext(client, options) {
|
|
|
950
985
|
const metadata = "metadata" in options2 ? options2.metadata : {};
|
|
951
986
|
const threadId = createThreadId();
|
|
952
987
|
const commentId = createCommentId();
|
|
953
|
-
const
|
|
988
|
+
const createdAt = /* @__PURE__ */ new Date();
|
|
954
989
|
const newComment = {
|
|
955
990
|
id: commentId,
|
|
956
991
|
threadId,
|
|
957
992
|
roomId: room.id,
|
|
958
|
-
createdAt
|
|
993
|
+
createdAt,
|
|
959
994
|
type: "comment",
|
|
960
995
|
userId: getCurrentUserId(room),
|
|
961
996
|
body,
|
|
@@ -964,7 +999,8 @@ function createRoomContext(client, options) {
|
|
|
964
999
|
const newThread = {
|
|
965
1000
|
id: threadId,
|
|
966
1001
|
type: "thread",
|
|
967
|
-
createdAt
|
|
1002
|
+
createdAt,
|
|
1003
|
+
updatedAt: createdAt,
|
|
968
1004
|
roomId: room.id,
|
|
969
1005
|
metadata,
|
|
970
1006
|
comments: [newComment]
|
|
@@ -975,7 +1011,7 @@ function createRoomContext(client, options) {
|
|
|
975
1011
|
thread: newThread,
|
|
976
1012
|
id: optimisticUpdateId
|
|
977
1013
|
});
|
|
978
|
-
room.createThread({ threadId, commentId, body, metadata }).then(
|
|
1014
|
+
room[kInternal].comments.createThread({ threadId, commentId, body, metadata }).then(
|
|
979
1015
|
(thread) => {
|
|
980
1016
|
store.set((state) => ({
|
|
981
1017
|
...state,
|
|
@@ -1014,31 +1050,55 @@ function createRoomContext(client, options) {
|
|
|
1014
1050
|
}
|
|
1015
1051
|
const threadId = options2.threadId;
|
|
1016
1052
|
const metadata = options2.metadata;
|
|
1053
|
+
const updatedAt = /* @__PURE__ */ new Date();
|
|
1017
1054
|
const optimisticUpdateId = nanoid2();
|
|
1018
1055
|
store.pushOptimisticUpdate({
|
|
1019
1056
|
type: "edit-thread-metadata",
|
|
1020
1057
|
metadata,
|
|
1021
1058
|
id: optimisticUpdateId,
|
|
1022
|
-
threadId
|
|
1059
|
+
threadId,
|
|
1060
|
+
updatedAt
|
|
1023
1061
|
});
|
|
1024
|
-
room.editThreadMetadata({ metadata, threadId }).then(
|
|
1062
|
+
room[kInternal].comments.editThreadMetadata({ metadata, threadId }).then(
|
|
1025
1063
|
(metadata2) => {
|
|
1026
|
-
store.set((state) =>
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
...state.threads,
|
|
1030
|
-
[threadId]: {
|
|
1031
|
-
...state.threads[threadId],
|
|
1032
|
-
metadata: {
|
|
1033
|
-
...state.threads[threadId].metadata,
|
|
1034
|
-
...metadata2
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
},
|
|
1038
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
1064
|
+
store.set((state) => {
|
|
1065
|
+
const existingThread = state.threads[threadId];
|
|
1066
|
+
const updatedOptimisticUpdates = state.optimisticUpdates.filter(
|
|
1039
1067
|
(update) => update.id !== optimisticUpdateId
|
|
1040
|
-
)
|
|
1041
|
-
|
|
1068
|
+
);
|
|
1069
|
+
if (existingThread === void 0) {
|
|
1070
|
+
return {
|
|
1071
|
+
...state,
|
|
1072
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1075
|
+
if (existingThread.deletedAt !== void 0) {
|
|
1076
|
+
return {
|
|
1077
|
+
...state,
|
|
1078
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
if (existingThread.updatedAt && existingThread.updatedAt > updatedAt) {
|
|
1082
|
+
return {
|
|
1083
|
+
...state,
|
|
1084
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1085
|
+
};
|
|
1086
|
+
}
|
|
1087
|
+
return {
|
|
1088
|
+
...state,
|
|
1089
|
+
threads: {
|
|
1090
|
+
...state.threads,
|
|
1091
|
+
[threadId]: {
|
|
1092
|
+
...existingThread,
|
|
1093
|
+
metadata: {
|
|
1094
|
+
...existingThread.metadata,
|
|
1095
|
+
...metadata2
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
},
|
|
1099
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1100
|
+
};
|
|
1101
|
+
});
|
|
1042
1102
|
},
|
|
1043
1103
|
(err) => onMutationFailure(
|
|
1044
1104
|
err,
|
|
@@ -1058,55 +1118,46 @@ function createRoomContext(client, options) {
|
|
|
1058
1118
|
const room = useRoom();
|
|
1059
1119
|
return React2.useCallback(
|
|
1060
1120
|
({ threadId, commentId, emoji }) => {
|
|
1061
|
-
const
|
|
1121
|
+
const createdAt = /* @__PURE__ */ new Date();
|
|
1062
1122
|
const userId = getCurrentUserId(room);
|
|
1063
1123
|
const optimisticUpdateId = nanoid2();
|
|
1064
1124
|
store.pushOptimisticUpdate({
|
|
1065
1125
|
type: "add-reaction",
|
|
1066
1126
|
threadId,
|
|
1067
1127
|
commentId,
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1128
|
+
reaction: {
|
|
1129
|
+
emoji,
|
|
1130
|
+
userId,
|
|
1131
|
+
createdAt
|
|
1132
|
+
},
|
|
1071
1133
|
id: optimisticUpdateId
|
|
1072
1134
|
});
|
|
1073
|
-
room.addReaction({ threadId, commentId, emoji }).then(
|
|
1135
|
+
room[kInternal].comments.addReaction({ threadId, commentId, emoji }).then(
|
|
1074
1136
|
(addedReaction) => {
|
|
1075
|
-
store.set((state) =>
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
...state.threads,
|
|
1079
|
-
[threadId]: {
|
|
1080
|
-
...state.threads[threadId],
|
|
1081
|
-
comments: state.threads[threadId].comments.map(
|
|
1082
|
-
(comment) => comment.id === commentId ? {
|
|
1083
|
-
...comment,
|
|
1084
|
-
reactions: comment.reactions.some(
|
|
1085
|
-
(reaction) => reaction.emoji === addedReaction.emoji
|
|
1086
|
-
) ? comment.reactions.map(
|
|
1087
|
-
(reaction) => reaction.emoji === addedReaction.emoji ? {
|
|
1088
|
-
...reaction,
|
|
1089
|
-
users: [
|
|
1090
|
-
...reaction.users,
|
|
1091
|
-
{ id: addedReaction.userId }
|
|
1092
|
-
]
|
|
1093
|
-
} : reaction
|
|
1094
|
-
) : [
|
|
1095
|
-
...comment.reactions,
|
|
1096
|
-
{
|
|
1097
|
-
emoji: addedReaction.emoji,
|
|
1098
|
-
createdAt: addedReaction.createdAt,
|
|
1099
|
-
users: [{ id: addedReaction.userId }]
|
|
1100
|
-
}
|
|
1101
|
-
]
|
|
1102
|
-
} : comment
|
|
1103
|
-
)
|
|
1104
|
-
}
|
|
1105
|
-
},
|
|
1106
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
1137
|
+
store.set((state) => {
|
|
1138
|
+
const existingThread = state.threads[threadId];
|
|
1139
|
+
const updatedOptimisticUpdates = state.optimisticUpdates.filter(
|
|
1107
1140
|
(update) => update.id !== optimisticUpdateId
|
|
1108
|
-
)
|
|
1109
|
-
|
|
1141
|
+
);
|
|
1142
|
+
if (existingThread === void 0) {
|
|
1143
|
+
return {
|
|
1144
|
+
...state,
|
|
1145
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1146
|
+
};
|
|
1147
|
+
}
|
|
1148
|
+
return {
|
|
1149
|
+
...state,
|
|
1150
|
+
threads: {
|
|
1151
|
+
...state.threads,
|
|
1152
|
+
[threadId]: addReaction(
|
|
1153
|
+
existingThread,
|
|
1154
|
+
commentId,
|
|
1155
|
+
addedReaction
|
|
1156
|
+
)
|
|
1157
|
+
},
|
|
1158
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1159
|
+
};
|
|
1160
|
+
});
|
|
1110
1161
|
},
|
|
1111
1162
|
(err) => onMutationFailure(
|
|
1112
1163
|
err,
|
|
@@ -1128,6 +1179,7 @@ function createRoomContext(client, options) {
|
|
|
1128
1179
|
return React2.useCallback(
|
|
1129
1180
|
({ threadId, commentId, emoji }) => {
|
|
1130
1181
|
const userId = getCurrentUserId(room);
|
|
1182
|
+
const removedAt = /* @__PURE__ */ new Date();
|
|
1131
1183
|
const optimisticUpdateId = nanoid2();
|
|
1132
1184
|
store.pushOptimisticUpdate({
|
|
1133
1185
|
type: "remove-reaction",
|
|
@@ -1135,50 +1187,37 @@ function createRoomContext(client, options) {
|
|
|
1135
1187
|
commentId,
|
|
1136
1188
|
emoji,
|
|
1137
1189
|
userId,
|
|
1190
|
+
removedAt,
|
|
1138
1191
|
id: optimisticUpdateId
|
|
1139
1192
|
});
|
|
1140
|
-
room.removeReaction({ threadId, commentId, emoji }).then(
|
|
1193
|
+
room[kInternal].comments.removeReaction({ threadId, commentId, emoji }).then(
|
|
1141
1194
|
() => {
|
|
1142
|
-
store.set((state) =>
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
...state.threads,
|
|
1146
|
-
[threadId]: {
|
|
1147
|
-
...state.threads[threadId],
|
|
1148
|
-
comments: state.threads[threadId].comments.map((comment) => {
|
|
1149
|
-
if (comment.id !== commentId) {
|
|
1150
|
-
return comment;
|
|
1151
|
-
}
|
|
1152
|
-
const reactionIndex = comment.reactions.findIndex(
|
|
1153
|
-
(reaction) => reaction.emoji === emoji
|
|
1154
|
-
);
|
|
1155
|
-
let reactions = comment.reactions;
|
|
1156
|
-
if (reactionIndex >= 0 && comment.reactions[reactionIndex].users.some(
|
|
1157
|
-
(user) => user.id === userId
|
|
1158
|
-
)) {
|
|
1159
|
-
if (comment.reactions[reactionIndex].users.length <= 1) {
|
|
1160
|
-
reactions = [...comment.reactions];
|
|
1161
|
-
reactions.splice(reactionIndex, 1);
|
|
1162
|
-
} else {
|
|
1163
|
-
reactions[reactionIndex] = {
|
|
1164
|
-
...reactions[reactionIndex],
|
|
1165
|
-
users: reactions[reactionIndex].users.filter(
|
|
1166
|
-
(user) => user.id !== userId
|
|
1167
|
-
)
|
|
1168
|
-
};
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
return {
|
|
1172
|
-
...comment,
|
|
1173
|
-
reactions
|
|
1174
|
-
};
|
|
1175
|
-
})
|
|
1176
|
-
}
|
|
1177
|
-
},
|
|
1178
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
1195
|
+
store.set((state) => {
|
|
1196
|
+
const existingThread = state.threads[threadId];
|
|
1197
|
+
const updatedOptimisticUpdates = state.optimisticUpdates.filter(
|
|
1179
1198
|
(update) => update.id !== optimisticUpdateId
|
|
1180
|
-
)
|
|
1181
|
-
|
|
1199
|
+
);
|
|
1200
|
+
if (existingThread === void 0) {
|
|
1201
|
+
return {
|
|
1202
|
+
...state,
|
|
1203
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1204
|
+
};
|
|
1205
|
+
}
|
|
1206
|
+
return {
|
|
1207
|
+
...state,
|
|
1208
|
+
threads: {
|
|
1209
|
+
...state.threads,
|
|
1210
|
+
[threadId]: removeReaction(
|
|
1211
|
+
existingThread,
|
|
1212
|
+
commentId,
|
|
1213
|
+
emoji,
|
|
1214
|
+
userId,
|
|
1215
|
+
removedAt
|
|
1216
|
+
)
|
|
1217
|
+
},
|
|
1218
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1219
|
+
};
|
|
1220
|
+
});
|
|
1182
1221
|
},
|
|
1183
1222
|
(err) => onMutationFailure(
|
|
1184
1223
|
err,
|
|
@@ -1200,44 +1239,58 @@ function createRoomContext(client, options) {
|
|
|
1200
1239
|
return React2.useCallback(
|
|
1201
1240
|
({ threadId, body }) => {
|
|
1202
1241
|
const commentId = createCommentId();
|
|
1203
|
-
const
|
|
1242
|
+
const createdAt = /* @__PURE__ */ new Date();
|
|
1204
1243
|
const comment = {
|
|
1205
1244
|
id: commentId,
|
|
1206
1245
|
threadId,
|
|
1207
1246
|
roomId: room.id,
|
|
1208
1247
|
type: "comment",
|
|
1209
|
-
createdAt
|
|
1248
|
+
createdAt,
|
|
1210
1249
|
userId: getCurrentUserId(room),
|
|
1211
1250
|
body,
|
|
1212
1251
|
reactions: []
|
|
1213
1252
|
};
|
|
1214
1253
|
const optimisticUpdateId = nanoid2();
|
|
1215
|
-
const inboxNotification = Object.values(
|
|
1216
|
-
store.get().inboxNotifications
|
|
1217
|
-
).find((inboxNotification2) => inboxNotification2.threadId === threadId);
|
|
1218
1254
|
store.pushOptimisticUpdate({
|
|
1219
1255
|
type: "create-comment",
|
|
1220
1256
|
comment,
|
|
1221
|
-
id: optimisticUpdateId
|
|
1222
|
-
inboxNotificationId: inboxNotification?.id
|
|
1257
|
+
id: optimisticUpdateId
|
|
1223
1258
|
});
|
|
1224
|
-
room.createComment({ threadId, commentId, body }).then(
|
|
1259
|
+
room[kInternal].comments.createComment({ threadId, commentId, body }).then(
|
|
1225
1260
|
(newComment) => {
|
|
1226
|
-
store.set((state) =>
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1261
|
+
store.set((state) => {
|
|
1262
|
+
const existingThread = state.threads[threadId];
|
|
1263
|
+
const updatedOptimisticUpdates = state.optimisticUpdates.filter(
|
|
1264
|
+
(update) => update.id !== optimisticUpdateId
|
|
1265
|
+
);
|
|
1266
|
+
if (existingThread === void 0) {
|
|
1267
|
+
return {
|
|
1268
|
+
...state,
|
|
1269
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1270
|
+
};
|
|
1271
|
+
}
|
|
1272
|
+
const inboxNotification = Object.values(
|
|
1273
|
+
state.inboxNotifications
|
|
1274
|
+
).find((notification) => notification.threadId === threadId);
|
|
1275
|
+
const updatedInboxNotifications = inboxNotification !== void 0 ? {
|
|
1230
1276
|
...state.inboxNotifications,
|
|
1231
1277
|
[inboxNotification.id]: {
|
|
1232
1278
|
...inboxNotification,
|
|
1233
1279
|
notifiedAt: newComment.createdAt,
|
|
1234
1280
|
readAt: newComment.createdAt
|
|
1235
1281
|
}
|
|
1236
|
-
} : state.inboxNotifications
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1282
|
+
} : state.inboxNotifications;
|
|
1283
|
+
return {
|
|
1284
|
+
...state,
|
|
1285
|
+
threads: {
|
|
1286
|
+
...state.threads,
|
|
1287
|
+
[threadId]: upsertComment(existingThread, newComment)
|
|
1288
|
+
// Upsert the new comment into the thread comments list (if applicable)
|
|
1289
|
+
},
|
|
1290
|
+
inboxNotifications: updatedInboxNotifications,
|
|
1291
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1292
|
+
};
|
|
1293
|
+
});
|
|
1241
1294
|
},
|
|
1242
1295
|
(err) => onMutationFailure(
|
|
1243
1296
|
err,
|
|
@@ -1259,25 +1312,56 @@ function createRoomContext(client, options) {
|
|
|
1259
1312
|
const room = useRoom();
|
|
1260
1313
|
return React2.useCallback(
|
|
1261
1314
|
({ threadId, commentId, body }) => {
|
|
1262
|
-
const
|
|
1315
|
+
const editedAt = /* @__PURE__ */ new Date();
|
|
1263
1316
|
const optimisticUpdateId = nanoid2();
|
|
1317
|
+
const thread = store.get().threads[threadId];
|
|
1318
|
+
if (thread === void 0) {
|
|
1319
|
+
console2.warn(
|
|
1320
|
+
`Internal unexpected behavior. Cannot edit comment in thread "${threadId}" because the thread does not exist in the cache.`
|
|
1321
|
+
);
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1324
|
+
const comment = thread.comments.find(
|
|
1325
|
+
(comment2) => comment2.id === commentId
|
|
1326
|
+
);
|
|
1327
|
+
if (comment === void 0 || comment.deletedAt !== void 0) {
|
|
1328
|
+
console2.warn(
|
|
1329
|
+
`Internal unexpected behavior. Cannot edit comment "${commentId}" in thread "${threadId}" because the comment does not exist in the cache.`
|
|
1330
|
+
);
|
|
1331
|
+
return;
|
|
1332
|
+
}
|
|
1264
1333
|
store.pushOptimisticUpdate({
|
|
1265
1334
|
type: "edit-comment",
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1335
|
+
comment: {
|
|
1336
|
+
...comment,
|
|
1337
|
+
editedAt,
|
|
1338
|
+
body
|
|
1339
|
+
},
|
|
1270
1340
|
id: optimisticUpdateId
|
|
1271
1341
|
});
|
|
1272
|
-
room.editComment({ threadId, commentId, body }).then(
|
|
1342
|
+
room[kInternal].comments.editComment({ threadId, commentId, body }).then(
|
|
1273
1343
|
(editedComment) => {
|
|
1274
|
-
store.set((state) =>
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
1344
|
+
store.set((state) => {
|
|
1345
|
+
const existingThread = state.threads[threadId];
|
|
1346
|
+
const updatedOptimisticUpdates = state.optimisticUpdates.filter(
|
|
1278
1347
|
(update) => update.id !== optimisticUpdateId
|
|
1279
|
-
)
|
|
1280
|
-
|
|
1348
|
+
);
|
|
1349
|
+
if (existingThread === void 0) {
|
|
1350
|
+
return {
|
|
1351
|
+
...state,
|
|
1352
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
return {
|
|
1356
|
+
...state,
|
|
1357
|
+
threads: {
|
|
1358
|
+
...state.threads,
|
|
1359
|
+
[threadId]: upsertComment(existingThread, editedComment)
|
|
1360
|
+
// Upsert the edited comment into the thread comments list (if applicable)
|
|
1361
|
+
},
|
|
1362
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1363
|
+
};
|
|
1364
|
+
});
|
|
1281
1365
|
},
|
|
1282
1366
|
(err) => onMutationFailure(
|
|
1283
1367
|
err,
|
|
@@ -1298,43 +1382,41 @@ function createRoomContext(client, options) {
|
|
|
1298
1382
|
const room = useRoom();
|
|
1299
1383
|
return React2.useCallback(
|
|
1300
1384
|
({ threadId, commentId }) => {
|
|
1301
|
-
const
|
|
1385
|
+
const deletedAt = /* @__PURE__ */ new Date();
|
|
1302
1386
|
const optimisticUpdateId = nanoid2();
|
|
1303
1387
|
store.pushOptimisticUpdate({
|
|
1304
1388
|
type: "delete-comment",
|
|
1305
1389
|
threadId,
|
|
1306
1390
|
commentId,
|
|
1307
|
-
deletedAt
|
|
1391
|
+
deletedAt,
|
|
1308
1392
|
id: optimisticUpdateId
|
|
1309
1393
|
});
|
|
1310
|
-
room.deleteComment({ threadId, commentId }).then(
|
|
1394
|
+
room[kInternal].comments.deleteComment({ threadId, commentId }).then(
|
|
1311
1395
|
() => {
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
return;
|
|
1316
|
-
newThreads[thread.id] = {
|
|
1317
|
-
...thread,
|
|
1318
|
-
comments: thread.comments.map(
|
|
1319
|
-
(comment) => comment.id === commentId ? {
|
|
1320
|
-
...comment,
|
|
1321
|
-
deletedAt: now,
|
|
1322
|
-
body: void 0
|
|
1323
|
-
} : comment
|
|
1324
|
-
)
|
|
1325
|
-
};
|
|
1326
|
-
if (!newThreads[thread.id].comments.some(
|
|
1327
|
-
(comment) => comment.deletedAt === void 0
|
|
1328
|
-
)) {
|
|
1329
|
-
delete newThreads[thread.id];
|
|
1330
|
-
}
|
|
1331
|
-
store.set((state) => ({
|
|
1332
|
-
...state,
|
|
1333
|
-
threads: newThreads,
|
|
1334
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
1396
|
+
store.set((state) => {
|
|
1397
|
+
const existingThread = state.threads[threadId];
|
|
1398
|
+
const updatedOptimisticUpdates = state.optimisticUpdates.filter(
|
|
1335
1399
|
(update) => update.id !== optimisticUpdateId
|
|
1336
|
-
)
|
|
1337
|
-
|
|
1400
|
+
);
|
|
1401
|
+
if (existingThread === void 0) {
|
|
1402
|
+
return {
|
|
1403
|
+
...state,
|
|
1404
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1405
|
+
};
|
|
1406
|
+
}
|
|
1407
|
+
return {
|
|
1408
|
+
...state,
|
|
1409
|
+
threads: {
|
|
1410
|
+
...state.threads,
|
|
1411
|
+
[threadId]: deleteComment(
|
|
1412
|
+
existingThread,
|
|
1413
|
+
commentId,
|
|
1414
|
+
deletedAt
|
|
1415
|
+
)
|
|
1416
|
+
},
|
|
1417
|
+
optimisticUpdates: updatedOptimisticUpdates
|
|
1418
|
+
};
|
|
1419
|
+
});
|
|
1338
1420
|
},
|
|
1339
1421
|
(err) => onMutationFailure(
|
|
1340
1422
|
err,
|
|
@@ -1402,10 +1484,7 @@ function createRoomContext(client, options) {
|
|
|
1402
1484
|
return mentionSuggestions;
|
|
1403
1485
|
}
|
|
1404
1486
|
function useThreadSubscription(threadId) {
|
|
1405
|
-
|
|
1406
|
-
store.subscribe,
|
|
1407
|
-
store.get,
|
|
1408
|
-
store.get,
|
|
1487
|
+
const selector = React2.useCallback(
|
|
1409
1488
|
(state) => {
|
|
1410
1489
|
const inboxNotification = selectedInboxNotifications(state).find(
|
|
1411
1490
|
(inboxNotification2) => inboxNotification2.threadId === threadId
|
|
@@ -1420,85 +1499,90 @@ function createRoomContext(client, options) {
|
|
|
1420
1499
|
status: "subscribed",
|
|
1421
1500
|
unreadSince: inboxNotification.readAt
|
|
1422
1501
|
};
|
|
1423
|
-
}
|
|
1502
|
+
},
|
|
1503
|
+
[threadId]
|
|
1504
|
+
);
|
|
1505
|
+
return useSyncExternalStoreWithSelector(
|
|
1506
|
+
store.subscribe,
|
|
1507
|
+
store.get,
|
|
1508
|
+
store.get,
|
|
1509
|
+
selector
|
|
1424
1510
|
);
|
|
1425
1511
|
}
|
|
1426
1512
|
function useMarkThreadAsRead() {
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
const now = /* @__PURE__ */ new Date();
|
|
1435
|
-
store.pushOptimisticUpdate({
|
|
1436
|
-
type: "mark-inbox-notification-as-read",
|
|
1437
|
-
id: optimisticUpdateId,
|
|
1438
|
-
inboxNotificationId: inboxNotification.id,
|
|
1439
|
-
readAt: now
|
|
1440
|
-
});
|
|
1441
|
-
client.markInboxNotificationAsRead(inboxNotification.id).then(
|
|
1442
|
-
() => {
|
|
1443
|
-
store.set((state) => ({
|
|
1444
|
-
...state,
|
|
1445
|
-
inboxNotifications: {
|
|
1446
|
-
...state.inboxNotifications,
|
|
1447
|
-
[inboxNotification.id]: {
|
|
1448
|
-
...inboxNotification,
|
|
1449
|
-
readAt: now
|
|
1450
|
-
}
|
|
1451
|
-
},
|
|
1452
|
-
optimisticUpdates: state.optimisticUpdates.filter(
|
|
1453
|
-
(update) => update.id !== optimisticUpdateId
|
|
1454
|
-
)
|
|
1455
|
-
}));
|
|
1456
|
-
},
|
|
1457
|
-
(err) => {
|
|
1458
|
-
onMutationFailure(
|
|
1459
|
-
err,
|
|
1460
|
-
optimisticUpdateId,
|
|
1461
|
-
(error) => new MarkInboxNotificationAsReadError(error, {
|
|
1462
|
-
inboxNotificationId: inboxNotification.id
|
|
1463
|
-
})
|
|
1464
|
-
);
|
|
1513
|
+
const room = useRoom();
|
|
1514
|
+
return React2.useCallback(
|
|
1515
|
+
(threadId) => {
|
|
1516
|
+
const inboxNotification = Object.values(
|
|
1517
|
+
store.get().inboxNotifications
|
|
1518
|
+
).find((inboxNotification2) => inboxNotification2.threadId === threadId);
|
|
1519
|
+
if (!inboxNotification)
|
|
1465
1520
|
return;
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1521
|
+
const optimisticUpdateId = nanoid2();
|
|
1522
|
+
const now = /* @__PURE__ */ new Date();
|
|
1523
|
+
store.pushOptimisticUpdate({
|
|
1524
|
+
type: "mark-inbox-notification-as-read",
|
|
1525
|
+
id: optimisticUpdateId,
|
|
1526
|
+
inboxNotificationId: inboxNotification.id,
|
|
1527
|
+
readAt: now
|
|
1528
|
+
});
|
|
1529
|
+
room[kInternal].notifications.markInboxNotificationAsRead(inboxNotification.id).then(
|
|
1530
|
+
() => {
|
|
1531
|
+
store.set((state) => ({
|
|
1532
|
+
...state,
|
|
1533
|
+
inboxNotifications: {
|
|
1534
|
+
...state.inboxNotifications,
|
|
1535
|
+
[inboxNotification.id]: {
|
|
1536
|
+
...inboxNotification,
|
|
1537
|
+
readAt: now
|
|
1538
|
+
}
|
|
1539
|
+
},
|
|
1540
|
+
optimisticUpdates: state.optimisticUpdates.filter(
|
|
1541
|
+
(update) => update.id !== optimisticUpdateId
|
|
1542
|
+
)
|
|
1543
|
+
}));
|
|
1544
|
+
},
|
|
1545
|
+
(err) => {
|
|
1546
|
+
onMutationFailure(
|
|
1547
|
+
err,
|
|
1548
|
+
optimisticUpdateId,
|
|
1549
|
+
(error) => new MarkInboxNotificationAsReadError(error, {
|
|
1550
|
+
inboxNotificationId: inboxNotification.id
|
|
1551
|
+
})
|
|
1552
|
+
);
|
|
1553
|
+
return;
|
|
1554
|
+
}
|
|
1555
|
+
);
|
|
1556
|
+
},
|
|
1557
|
+
[room]
|
|
1558
|
+
);
|
|
1469
1559
|
}
|
|
1470
1560
|
function makeNotificationSettingsQueryKey(roomId) {
|
|
1471
1561
|
return `${roomId}:NOTIFICATION_SETTINGS`;
|
|
1472
1562
|
}
|
|
1473
1563
|
async function getInboxNotificationSettings(room, queryKey) {
|
|
1474
|
-
const
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
}
|
|
1497
|
-
}
|
|
1498
|
-
}));
|
|
1499
|
-
}
|
|
1500
|
-
}
|
|
1501
|
-
);
|
|
1564
|
+
const requestInfo = requestsCache.get(queryKey);
|
|
1565
|
+
if (requestInfo !== void 0) {
|
|
1566
|
+
return requestInfo.promise;
|
|
1567
|
+
}
|
|
1568
|
+
const promise = room[kInternal].notifications.getRoomNotificationSettings();
|
|
1569
|
+
requestsCache.set(queryKey, {
|
|
1570
|
+
promise,
|
|
1571
|
+
subscribers: 0
|
|
1572
|
+
});
|
|
1573
|
+
store.setQueryState(queryKey, {
|
|
1574
|
+
isLoading: true
|
|
1575
|
+
});
|
|
1576
|
+
try {
|
|
1577
|
+
const settings = await promise;
|
|
1578
|
+
store.updateRoomInboxNotificationSettings(room.id, settings, queryKey);
|
|
1579
|
+
} catch (err) {
|
|
1580
|
+
store.setQueryState(queryKey, {
|
|
1581
|
+
isLoading: false,
|
|
1582
|
+
error: err
|
|
1583
|
+
});
|
|
1584
|
+
}
|
|
1585
|
+
poller.start(POLLING_INTERVAL);
|
|
1502
1586
|
}
|
|
1503
1587
|
function useRoomNotificationSettings() {
|
|
1504
1588
|
const room = useRoom();
|
|
@@ -1509,27 +1593,31 @@ function createRoomContext(client, options) {
|
|
|
1509
1593
|
return () => decrementQuerySubscribers(queryKey);
|
|
1510
1594
|
}, [room]);
|
|
1511
1595
|
const updateRoomNotificationSettings = useUpdateRoomNotificationSettings();
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
(state) => {
|
|
1518
|
-
const query = state.queries[makeNotificationSettingsQueryKey(room.id)];
|
|
1519
|
-
if (query === void 0 || query.isLoading) {
|
|
1520
|
-
return { isLoading: true };
|
|
1521
|
-
}
|
|
1522
|
-
if (query.error !== void 0) {
|
|
1523
|
-
return { isLoading: false, error: query.error };
|
|
1524
|
-
}
|
|
1525
|
-
return {
|
|
1526
|
-
isLoading: false,
|
|
1527
|
-
settings: selectNotificationSettings(room.id, state)
|
|
1528
|
-
};
|
|
1596
|
+
const selector = React2.useCallback(
|
|
1597
|
+
(state) => {
|
|
1598
|
+
const query = state.queries[makeNotificationSettingsQueryKey(room.id)];
|
|
1599
|
+
if (query === void 0 || query.isLoading) {
|
|
1600
|
+
return { isLoading: true };
|
|
1529
1601
|
}
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1602
|
+
if (query.error !== void 0) {
|
|
1603
|
+
return { isLoading: false, error: query.error };
|
|
1604
|
+
}
|
|
1605
|
+
return {
|
|
1606
|
+
isLoading: false,
|
|
1607
|
+
settings: selectNotificationSettings(room.id, state)
|
|
1608
|
+
};
|
|
1609
|
+
},
|
|
1610
|
+
[room]
|
|
1611
|
+
);
|
|
1612
|
+
const settings = useSyncExternalStoreWithSelector(
|
|
1613
|
+
store.subscribe,
|
|
1614
|
+
store.get,
|
|
1615
|
+
store.get,
|
|
1616
|
+
selector
|
|
1617
|
+
);
|
|
1618
|
+
return React2.useMemo(() => {
|
|
1619
|
+
return [settings, updateRoomNotificationSettings];
|
|
1620
|
+
}, [settings, updateRoomNotificationSettings]);
|
|
1533
1621
|
}
|
|
1534
1622
|
function useRoomNotificationSettingsSuspense() {
|
|
1535
1623
|
const updateRoomNotificationSettings = useUpdateRoomNotificationSettings();
|
|
@@ -1547,20 +1635,24 @@ function createRoomContext(client, options) {
|
|
|
1547
1635
|
incrementQuerySubscribers(queryKey2);
|
|
1548
1636
|
return () => decrementQuerySubscribers(queryKey2);
|
|
1549
1637
|
}, [room]);
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1638
|
+
const selector = React2.useCallback(
|
|
1639
|
+
(state) => {
|
|
1640
|
+
return {
|
|
1641
|
+
isLoading: false,
|
|
1642
|
+
settings: selectNotificationSettings(room.id, state)
|
|
1643
|
+
};
|
|
1644
|
+
},
|
|
1645
|
+
[room]
|
|
1646
|
+
);
|
|
1647
|
+
const settings = useSyncExternalStoreWithSelector(
|
|
1648
|
+
store.subscribe,
|
|
1649
|
+
store.get,
|
|
1650
|
+
store.get,
|
|
1651
|
+
selector
|
|
1652
|
+
);
|
|
1653
|
+
return React2.useMemo(() => {
|
|
1654
|
+
return [settings, updateRoomNotificationSettings];
|
|
1655
|
+
}, [settings, updateRoomNotificationSettings]);
|
|
1564
1656
|
}
|
|
1565
1657
|
function useUpdateRoomNotificationSettings() {
|
|
1566
1658
|
const room = useRoom();
|
|
@@ -1573,7 +1665,7 @@ function createRoomContext(client, options) {
|
|
|
1573
1665
|
roomId: room.id,
|
|
1574
1666
|
settings
|
|
1575
1667
|
});
|
|
1576
|
-
room.updateRoomNotificationSettings(settings).then(
|
|
1668
|
+
room[kInternal].notifications.updateRoomNotificationSettings(settings).then(
|
|
1577
1669
|
(settings2) => {
|
|
1578
1670
|
store.set((state) => ({
|
|
1579
1671
|
...state,
|
|
@@ -1799,13 +1891,13 @@ function createSharedContext(client) {
|
|
|
1799
1891
|
);
|
|
1800
1892
|
const roomInfoState = getRoomInfoState();
|
|
1801
1893
|
if (!roomInfoState || roomInfoState.isLoading) {
|
|
1802
|
-
throw
|
|
1894
|
+
throw roomsInfoStore.get(roomId);
|
|
1803
1895
|
}
|
|
1804
1896
|
if (roomInfoState.error) {
|
|
1805
1897
|
throw roomInfoState.error;
|
|
1806
1898
|
}
|
|
1807
1899
|
const state = useSyncExternalStore2(
|
|
1808
|
-
|
|
1900
|
+
roomsInfoStore.subscribe,
|
|
1809
1901
|
getRoomInfoState,
|
|
1810
1902
|
getRoomInfoState
|
|
1811
1903
|
);
|
|
@@ -1834,9 +1926,12 @@ function useLiveblocksContextBundle() {
|
|
|
1834
1926
|
}
|
|
1835
1927
|
return bundle;
|
|
1836
1928
|
}
|
|
1929
|
+
var POLLING_INTERVAL2 = 60 * 1e3;
|
|
1930
|
+
var INBOX_NOTIFICATIONS_QUERY = "INBOX_NOTIFICATIONS";
|
|
1837
1931
|
function createLiveblocksContext(client) {
|
|
1838
1932
|
const shared = createSharedContext(client);
|
|
1839
1933
|
const store = client[kInternal3].cacheStore;
|
|
1934
|
+
const notifications = client[kInternal3].notifications;
|
|
1840
1935
|
function LiveblocksProvider(props) {
|
|
1841
1936
|
return /* @__PURE__ */ React3.createElement(
|
|
1842
1937
|
ContextBundle2.Provider,
|
|
@@ -1848,15 +1943,17 @@ function createLiveblocksContext(client) {
|
|
|
1848
1943
|
}
|
|
1849
1944
|
let fetchInboxNotificationsRequest = null;
|
|
1850
1945
|
let inboxNotificationsSubscribers = 0;
|
|
1851
|
-
|
|
1852
|
-
const POLLING_INTERVAL2 = 60 * 1e3;
|
|
1946
|
+
let lastRequestedAt;
|
|
1853
1947
|
const poller = makePoller2(refreshThreadsAndNotifications);
|
|
1854
1948
|
function refreshThreadsAndNotifications() {
|
|
1855
|
-
return
|
|
1856
|
-
(
|
|
1949
|
+
return notifications.getInboxNotifications({ since: lastRequestedAt }).then(
|
|
1950
|
+
(result) => {
|
|
1951
|
+
lastRequestedAt = result.meta.requestedAt;
|
|
1857
1952
|
store.updateThreadsAndNotifications(
|
|
1858
|
-
threads,
|
|
1859
|
-
inboxNotifications,
|
|
1953
|
+
result.threads,
|
|
1954
|
+
result.inboxNotifications,
|
|
1955
|
+
result.deletedThreads,
|
|
1956
|
+
result.deletedInboxNotifications,
|
|
1860
1957
|
INBOX_NOTIFICATIONS_QUERY
|
|
1861
1958
|
);
|
|
1862
1959
|
},
|
|
@@ -1888,13 +1985,18 @@ function createLiveblocksContext(client) {
|
|
|
1888
1985
|
isLoading: true
|
|
1889
1986
|
});
|
|
1890
1987
|
try {
|
|
1891
|
-
fetchInboxNotificationsRequest =
|
|
1892
|
-
const
|
|
1988
|
+
fetchInboxNotificationsRequest = notifications.getInboxNotifications();
|
|
1989
|
+
const result = await fetchInboxNotificationsRequest;
|
|
1893
1990
|
store.updateThreadsAndNotifications(
|
|
1894
|
-
threads,
|
|
1895
|
-
inboxNotifications,
|
|
1991
|
+
result.threads,
|
|
1992
|
+
result.inboxNotifications,
|
|
1993
|
+
result.deletedThreads,
|
|
1994
|
+
result.deletedInboxNotifications,
|
|
1896
1995
|
INBOX_NOTIFICATIONS_QUERY
|
|
1897
1996
|
);
|
|
1997
|
+
if (lastRequestedAt === void 0 || lastRequestedAt > result.meta.requestedAt) {
|
|
1998
|
+
lastRequestedAt = result.meta.requestedAt;
|
|
1999
|
+
}
|
|
1898
2000
|
} catch (er) {
|
|
1899
2001
|
store.setQueryState(INBOX_NOTIFICATIONS_QUERY, {
|
|
1900
2002
|
isLoading: false,
|
|
@@ -1903,39 +2005,47 @@ function createLiveblocksContext(client) {
|
|
|
1903
2005
|
}
|
|
1904
2006
|
return;
|
|
1905
2007
|
}
|
|
2008
|
+
function useInboxNotificationsSelectorCallback(state) {
|
|
2009
|
+
const query = state.queries[INBOX_NOTIFICATIONS_QUERY];
|
|
2010
|
+
if (query === void 0 || query.isLoading) {
|
|
2011
|
+
return {
|
|
2012
|
+
isLoading: true
|
|
2013
|
+
};
|
|
2014
|
+
}
|
|
2015
|
+
if (query.error !== void 0) {
|
|
2016
|
+
return {
|
|
2017
|
+
error: query.error,
|
|
2018
|
+
isLoading: false
|
|
2019
|
+
};
|
|
2020
|
+
}
|
|
2021
|
+
return {
|
|
2022
|
+
inboxNotifications: selectedInboxNotifications(state),
|
|
2023
|
+
isLoading: false
|
|
2024
|
+
};
|
|
2025
|
+
}
|
|
1906
2026
|
function useInboxNotifications() {
|
|
1907
2027
|
useEffect5(() => {
|
|
1908
2028
|
void fetchInboxNotifications();
|
|
1909
2029
|
incrementInboxNotificationsSubscribers();
|
|
1910
2030
|
return () => decrementInboxNotificationsSubscribers();
|
|
1911
|
-
});
|
|
2031
|
+
}, []);
|
|
1912
2032
|
const result = useSyncExternalStoreWithSelector2(
|
|
1913
2033
|
store.subscribe,
|
|
1914
2034
|
store.get,
|
|
1915
2035
|
store.get,
|
|
1916
|
-
|
|
1917
|
-
const query = state.queries[INBOX_NOTIFICATIONS_QUERY];
|
|
1918
|
-
if (query === void 0 || query.isLoading) {
|
|
1919
|
-
return {
|
|
1920
|
-
isLoading: true
|
|
1921
|
-
};
|
|
1922
|
-
}
|
|
1923
|
-
if (query.error !== void 0) {
|
|
1924
|
-
return {
|
|
1925
|
-
error: query.error,
|
|
1926
|
-
isLoading: false
|
|
1927
|
-
};
|
|
1928
|
-
}
|
|
1929
|
-
return {
|
|
1930
|
-
inboxNotifications: selectedInboxNotifications(state),
|
|
1931
|
-
isLoading: false
|
|
1932
|
-
};
|
|
1933
|
-
}
|
|
2036
|
+
useInboxNotificationsSelectorCallback
|
|
1934
2037
|
);
|
|
1935
2038
|
return result;
|
|
1936
2039
|
}
|
|
2040
|
+
function useInboxNotificationsSuspenseSelector(state) {
|
|
2041
|
+
return {
|
|
2042
|
+
inboxNotifications: selectedInboxNotifications(state),
|
|
2043
|
+
isLoading: false
|
|
2044
|
+
};
|
|
2045
|
+
}
|
|
1937
2046
|
function useInboxNotificationsSuspense() {
|
|
1938
|
-
|
|
2047
|
+
const query = store.get().queries[INBOX_NOTIFICATIONS_QUERY];
|
|
2048
|
+
if (query === void 0 || query.isLoading) {
|
|
1939
2049
|
throw fetchInboxNotifications();
|
|
1940
2050
|
}
|
|
1941
2051
|
React3.useEffect(() => {
|
|
@@ -1948,12 +2058,7 @@ function createLiveblocksContext(client) {
|
|
|
1948
2058
|
store.subscribe,
|
|
1949
2059
|
store.get,
|
|
1950
2060
|
store.get,
|
|
1951
|
-
|
|
1952
|
-
return {
|
|
1953
|
-
inboxNotifications: selectedInboxNotifications(state),
|
|
1954
|
-
isLoading: false
|
|
1955
|
-
};
|
|
1956
|
-
}
|
|
2061
|
+
useInboxNotificationsSuspenseSelector
|
|
1957
2062
|
);
|
|
1958
2063
|
}
|
|
1959
2064
|
function selectUnreadInboxNotificationsCount(state) {
|
|
@@ -1965,38 +2070,46 @@ function createLiveblocksContext(client) {
|
|
|
1965
2070
|
}
|
|
1966
2071
|
return count;
|
|
1967
2072
|
}
|
|
2073
|
+
function useUnreadInboxNotificationsCountSelector(state) {
|
|
2074
|
+
const query = state.queries[INBOX_NOTIFICATIONS_QUERY];
|
|
2075
|
+
if (query === void 0 || query.isLoading) {
|
|
2076
|
+
return {
|
|
2077
|
+
isLoading: true
|
|
2078
|
+
};
|
|
2079
|
+
}
|
|
2080
|
+
if (query.error !== void 0) {
|
|
2081
|
+
return {
|
|
2082
|
+
error: query.error,
|
|
2083
|
+
isLoading: false
|
|
2084
|
+
};
|
|
2085
|
+
}
|
|
2086
|
+
return {
|
|
2087
|
+
isLoading: false,
|
|
2088
|
+
count: selectUnreadInboxNotificationsCount(state)
|
|
2089
|
+
};
|
|
2090
|
+
}
|
|
1968
2091
|
function useUnreadInboxNotificationsCount() {
|
|
1969
2092
|
useEffect5(() => {
|
|
1970
2093
|
void fetchInboxNotifications();
|
|
1971
2094
|
incrementInboxNotificationsSubscribers();
|
|
1972
2095
|
return () => decrementInboxNotificationsSubscribers();
|
|
1973
|
-
});
|
|
2096
|
+
}, []);
|
|
1974
2097
|
return useSyncExternalStoreWithSelector2(
|
|
1975
2098
|
store.subscribe,
|
|
1976
2099
|
store.get,
|
|
1977
2100
|
store.get,
|
|
1978
|
-
|
|
1979
|
-
const query = store.get().queries[INBOX_NOTIFICATIONS_QUERY];
|
|
1980
|
-
if (query === void 0 || query.isLoading) {
|
|
1981
|
-
return {
|
|
1982
|
-
isLoading: true
|
|
1983
|
-
};
|
|
1984
|
-
}
|
|
1985
|
-
if (query.error !== void 0) {
|
|
1986
|
-
return {
|
|
1987
|
-
error: query.error,
|
|
1988
|
-
isLoading: false
|
|
1989
|
-
};
|
|
1990
|
-
}
|
|
1991
|
-
return {
|
|
1992
|
-
isLoading: false,
|
|
1993
|
-
count: selectUnreadInboxNotificationsCount(state)
|
|
1994
|
-
};
|
|
1995
|
-
}
|
|
2101
|
+
useUnreadInboxNotificationsCountSelector
|
|
1996
2102
|
);
|
|
1997
2103
|
}
|
|
2104
|
+
function useUnreadInboxNotificationsCountSuspenseSelector(state) {
|
|
2105
|
+
return {
|
|
2106
|
+
isLoading: false,
|
|
2107
|
+
count: selectUnreadInboxNotificationsCount(state)
|
|
2108
|
+
};
|
|
2109
|
+
}
|
|
1998
2110
|
function useUnreadInboxNotificationsCountSuspense() {
|
|
1999
|
-
|
|
2111
|
+
const query = store.get().queries[INBOX_NOTIFICATIONS_QUERY];
|
|
2112
|
+
if (query === void 0 || query.isLoading) {
|
|
2000
2113
|
throw fetchInboxNotifications();
|
|
2001
2114
|
}
|
|
2002
2115
|
React3.useEffect(() => {
|
|
@@ -2009,12 +2122,7 @@ function createLiveblocksContext(client) {
|
|
|
2009
2122
|
store.subscribe,
|
|
2010
2123
|
store.get,
|
|
2011
2124
|
store.get,
|
|
2012
|
-
|
|
2013
|
-
return {
|
|
2014
|
-
isLoading: false,
|
|
2015
|
-
count: selectUnreadInboxNotificationsCount(state)
|
|
2016
|
-
};
|
|
2017
|
-
}
|
|
2125
|
+
useUnreadInboxNotificationsCountSuspenseSelector
|
|
2018
2126
|
);
|
|
2019
2127
|
}
|
|
2020
2128
|
function useMarkInboxNotificationAsRead() {
|
|
@@ -2027,22 +2135,32 @@ function createLiveblocksContext(client) {
|
|
|
2027
2135
|
inboxNotificationId,
|
|
2028
2136
|
readAt
|
|
2029
2137
|
});
|
|
2030
|
-
|
|
2138
|
+
notifications.markInboxNotificationAsRead(inboxNotificationId).then(
|
|
2031
2139
|
() => {
|
|
2032
|
-
store.set((state) =>
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
}
|
|
2041
|
-
}
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2140
|
+
store.set((state) => {
|
|
2141
|
+
const existingNotification = state.inboxNotifications[inboxNotificationId];
|
|
2142
|
+
if (existingNotification === void 0) {
|
|
2143
|
+
return {
|
|
2144
|
+
...state,
|
|
2145
|
+
optimisticUpdates: state.optimisticUpdates.filter(
|
|
2146
|
+
(update) => update.id !== optimisticUpdateId
|
|
2147
|
+
)
|
|
2148
|
+
};
|
|
2149
|
+
}
|
|
2150
|
+
return {
|
|
2151
|
+
...state,
|
|
2152
|
+
inboxNotifications: {
|
|
2153
|
+
...state.inboxNotifications,
|
|
2154
|
+
[inboxNotificationId]: {
|
|
2155
|
+
...existingNotification,
|
|
2156
|
+
readAt
|
|
2157
|
+
}
|
|
2158
|
+
},
|
|
2159
|
+
optimisticUpdates: state.optimisticUpdates.filter(
|
|
2160
|
+
(update) => update.id !== optimisticUpdateId
|
|
2161
|
+
)
|
|
2162
|
+
};
|
|
2163
|
+
});
|
|
2046
2164
|
},
|
|
2047
2165
|
() => {
|
|
2048
2166
|
store.set((state) => ({
|
|
@@ -2064,7 +2182,7 @@ function createLiveblocksContext(client) {
|
|
|
2064
2182
|
id: optimisticUpdateId,
|
|
2065
2183
|
readAt
|
|
2066
2184
|
});
|
|
2067
|
-
|
|
2185
|
+
notifications.markAllInboxNotificationsAsRead().then(
|
|
2068
2186
|
() => {
|
|
2069
2187
|
store.set((state) => ({
|
|
2070
2188
|
...state,
|
|
@@ -2093,10 +2211,7 @@ function createLiveblocksContext(client) {
|
|
|
2093
2211
|
}, []);
|
|
2094
2212
|
}
|
|
2095
2213
|
function useThreadFromCache(threadId) {
|
|
2096
|
-
|
|
2097
|
-
store.subscribe,
|
|
2098
|
-
store.get,
|
|
2099
|
-
store.get,
|
|
2214
|
+
const selector = useCallback3(
|
|
2100
2215
|
(state) => {
|
|
2101
2216
|
const thread = state.threads[threadId];
|
|
2102
2217
|
if (thread === void 0) {
|
|
@@ -2105,7 +2220,14 @@ function createLiveblocksContext(client) {
|
|
|
2105
2220
|
);
|
|
2106
2221
|
}
|
|
2107
2222
|
return thread;
|
|
2108
|
-
}
|
|
2223
|
+
},
|
|
2224
|
+
[threadId]
|
|
2225
|
+
);
|
|
2226
|
+
return useSyncExternalStoreWithSelector2(
|
|
2227
|
+
store.subscribe,
|
|
2228
|
+
store.get,
|
|
2229
|
+
store.get,
|
|
2230
|
+
selector
|
|
2109
2231
|
);
|
|
2110
2232
|
}
|
|
2111
2233
|
const currentUserIdStore = client[kInternal3].currentUserIdStore;
|