Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3011533
D13375.id44329.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
D13375.id44329.diff
View Options
diff --git a/lib/shared/dm-ops/dm-ops-queue-handler.react.js b/lib/shared/dm-ops/dm-ops-queue-handler.react.js
--- a/lib/shared/dm-ops/dm-ops-queue-handler.react.js
+++ b/lib/shared/dm-ops/dm-ops-queue-handler.react.js
@@ -4,11 +4,19 @@
import { dmOperationSpecificationTypes } from './dm-op-utils.js';
import { useProcessDMOperation } from './process-dm-ops.js';
-import { threadInfoSelector } from '../../selectors/thread-selectors.js';
+import { messageInfoSelector } from '../../selectors/chat-selectors.js';
import {
+ entryInfoSelector,
+ threadInfoSelector,
+} from '../../selectors/thread-selectors.js';
+import {
+ clearQueuedEntryDMOpsActionType,
+ clearQueuedMembershipDMOpsActionType,
+ clearQueuedMessageDMOpsActionType,
clearQueuedThreadDMOpsActionType,
pruneDMOpsQueueActionType,
} from '../../types/dm-ops.js';
+import { threadTypeIsThick } from '../../types/thread-types-enum.js';
import { useDispatch, useSelector } from '../../utils/redux-utils.js';
const PRUNING_FREQUENCY = 60 * 60 * 1000;
@@ -40,12 +48,17 @@
const threadInfos = useSelector(threadInfoSelector);
const threadIDs = React.useMemo(
- () => new Set(Object.keys(threadInfos)),
+ () =>
+ new Set(
+ Object.entries(threadInfos)
+ .filter(([, threadInfo]) => threadTypeIsThick(threadInfo.type))
+ .map(([id]) => id),
+ ),
[threadInfos],
);
const prevThreadIDsRef = React.useRef<$ReadOnlySet<string>>(new Set());
- const queuedOperations = useSelector(
+ const queuedThreadOperations = useSelector(
state => state.queuedDMOperations.threadQueue,
);
@@ -55,11 +68,11 @@
const prevThreadIDs = prevThreadIDsRef.current;
prevThreadIDsRef.current = threadIDs;
- for (const threadID in queuedOperations) {
+ for (const threadID in queuedThreadOperations) {
if (!threadIDs.has(threadID) || prevThreadIDs.has(threadID)) {
continue;
}
- for (const dmOp of queuedOperations[threadID]) {
+ for (const dmOp of queuedThreadOperations[threadID]) {
void processDMOperation({
// This is `INBOUND` because we assume that when generating
// `dmOperationSpecificationTypes.OUBOUND` it should be possible
@@ -79,7 +92,161 @@
},
});
}
- }, [dispatch, processDMOperation, queuedOperations, threadIDs]);
+ }, [dispatch, processDMOperation, queuedThreadOperations, threadIDs]);
+
+ const messageInfos = useSelector(messageInfoSelector);
+ const messageIDs = React.useMemo(
+ () =>
+ new Set(
+ Object.entries(messageInfos)
+ .filter(
+ ([, messageInfo]) =>
+ messageInfo &&
+ threadTypeIsThick(threadInfos[messageInfo.threadID]?.type),
+ )
+ .map(([id]) => id),
+ ),
+ [messageInfos, threadInfos],
+ );
+ const prevMessageIDsRef = React.useRef<$ReadOnlySet<string>>(new Set());
+
+ const queuedMessageOperations = useSelector(
+ state => state.queuedDMOperations.messageQueue,
+ );
+
+ React.useEffect(() => {
+ const prevMessageIDs = prevMessageIDsRef.current;
+ prevMessageIDsRef.current = messageIDs;
+
+ for (const messageID in queuedMessageOperations) {
+ if (!messageIDs.has(messageID) || prevMessageIDs.has(messageID)) {
+ continue;
+ }
+
+ for (const dmOp of queuedMessageOperations[messageID]) {
+ void processDMOperation({
+ // This is `INBOUND` because we assume that when generating
+ // `dmOperationSpecificationTypes.OUBOUND` it should be possible
+ // to be processed and never queued up.
+ type: dmOperationSpecificationTypes.INBOUND,
+ op: dmOp.operation,
+ // There is no metadata, because messages were confirmed when
+ // adding to the queue.
+ metadata: null,
+ });
+ }
+
+ dispatch({
+ type: clearQueuedMessageDMOpsActionType,
+ payload: {
+ messageID,
+ },
+ });
+ }
+ }, [dispatch, messageIDs, processDMOperation, queuedMessageOperations]);
+
+ const entryInfos = useSelector(entryInfoSelector);
+ const entryIDs = React.useMemo(
+ () =>
+ new Set(
+ Object.entries(entryInfos)
+ .filter(([, entryInfo]) =>
+ threadTypeIsThick(threadInfos[entryInfo.threadID]?.type),
+ )
+ .map(([id]) => id),
+ ),
+ [entryInfos, threadInfos],
+ );
+ const prevEntryIDsRef = React.useRef<$ReadOnlySet<string>>(new Set());
+
+ const queuedEntryOperations = useSelector(
+ state => state.queuedDMOperations.entryQueue,
+ );
+
+ React.useEffect(() => {
+ const prevEntryIDs = prevEntryIDsRef.current;
+ prevEntryIDsRef.current = entryIDs;
+
+ for (const entryID in queuedEntryOperations) {
+ if (!entryIDs.has(entryID) || prevEntryIDs.has(entryID)) {
+ continue;
+ }
+
+ for (const dmOp of queuedEntryOperations[entryID]) {
+ void processDMOperation({
+ // This is `INBOUND` because we assume that when generating
+ // `dmOperationSpecificationTypes.OUBOUND` it should be possible
+ // to be processed and never queued up.
+ type: dmOperationSpecificationTypes.INBOUND,
+ op: dmOp.operation,
+ // There is no metadata, because messages were confirmed when
+ // adding to the queue.
+ metadata: null,
+ });
+ }
+
+ dispatch({
+ type: clearQueuedEntryDMOpsActionType,
+ payload: {
+ entryID,
+ },
+ });
+ }
+ }, [dispatch, entryIDs, processDMOperation, queuedEntryOperations]);
+
+ const queuedMembershipOperations = useSelector(
+ state => state.queuedDMOperations.membershipQueue,
+ );
+
+ const runningMembershipOperations = React.useRef<Map<string, Set<string>>>(
+ new Map(),
+ );
+ React.useEffect(() => {
+ for (const threadID in queuedMembershipOperations) {
+ if (!threadInfos[threadID]) {
+ continue;
+ }
+
+ const queuedMemberIDs = new Set(
+ Object.keys(queuedMembershipOperations[threadID]),
+ );
+ if (!runningMembershipOperations.current.has(threadID)) {
+ runningMembershipOperations.current.set(threadID, new Set());
+ }
+ for (const member of threadInfos[threadID].members) {
+ if (
+ !queuedMemberIDs.has(member.id) ||
+ runningMembershipOperations.current.get(threadID)?.has(member.id)
+ ) {
+ continue;
+ }
+
+ runningMembershipOperations.current.get(threadID)?.add(member.id);
+
+ for (const dmOp of queuedMembershipOperations[threadID][member.id]) {
+ void processDMOperation({
+ // This is `INBOUND` because we assume that when generating
+ // `dmOperationSpecificationTypes.OUBOUND` it should be possible
+ // to be processed and never queued up.
+ type: dmOperationSpecificationTypes.INBOUND,
+ op: dmOp.operation,
+ // There is no metadata, because messages were confirmed when
+ // adding to the queue.
+ metadata: null,
+ });
+ }
+
+ dispatch({
+ type: clearQueuedMembershipDMOpsActionType,
+ payload: {
+ threadID,
+ userID: member.id,
+ },
+ });
+ runningMembershipOperations.current.get(threadID)?.delete(member.id);
+ }
+ }
+ }, [dispatch, processDMOperation, queuedMembershipOperations, threadInfos]);
return null;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 20, 1:25 AM (22 h, 3 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2328242
Default Alt Text
D13375.id44329.diff (7 KB)
Attached To
Mode
D13375: [lib] Take operations from the queue when conditions become met
Attached
Detach File
Event Timeline
Log In to Comment