@towns-protocol/sdk
Version:
For more details, visit the following resources:
85 lines • 3.79 kB
JavaScript
import { getMutedChannelIds } from '../../notificationsClient';
import { isEqual } from 'lodash-es';
import { isChannelStreamId, spaceIdFromChannelId } from '../../id';
export function spaceUnreadsTransform(input, _prevInput, prev) {
const { myUnreadMarkers, timelinesView, notificationSettings } = input;
const mutedChannelIds = getMutedChannelIds(notificationSettings);
let next = prev ??
{
spaceUnreads: {},
spaceMentions: {},
spaceUnreadChannelIds: {},
};
const updateState = (spaceId, hasUnread, mentions, unreadChannelIds, prev) => {
const unreadChannelIdsArray = new Set(unreadChannelIds);
const channelIdsAreEqual = isEqual(prev.spaceUnreadChannelIds[spaceId], unreadChannelIdsArray);
if (prev.spaceUnreads[spaceId] === hasUnread &&
prev.spaceMentions[spaceId] === mentions &&
channelIdsAreEqual) {
return prev;
}
const spaceUnreads = prev.spaceUnreads[spaceId] === hasUnread
? prev.spaceUnreads
: { ...prev.spaceUnreads, [spaceId]: hasUnread };
const spaceMentions = prev.spaceMentions[spaceId] === mentions
? prev.spaceMentions
: { ...prev.spaceMentions, [spaceId]: mentions };
const spaceUnreadChannelIds = channelIdsAreEqual
? prev.spaceUnreadChannelIds
: { ...prev.spaceUnreadChannelIds, [spaceId]: unreadChannelIdsArray };
return {
spaceUnreads,
spaceMentions,
spaceUnreadChannelIds,
};
};
const markers = myUnreadMarkers.markers;
const threadsStats = timelinesView.threadsStats;
const results = {};
// we have lots of markers! loop over the markers just once and build up the state
// we should transition updating on a delta of markers
Object.entries(markers).forEach(([key, marker]) => {
// fixes symptoms of HNT-10960 by filtering out markers with
// empty keys. We should be able to remove this once the root
// cause has been in production for a while.
if (!key) {
return;
}
// only process channel markers
if (isChannelStreamId(marker.channelId)) {
const spaceId = spaceIdFromChannelId(marker.channelId);
// only return the unreads from spaceIds in the spaceId store
if (!results[spaceId]) {
results[spaceId] = {
isUnread: false,
mentions: 0,
unreadChannelIds: new Set(),
};
}
if (marker.isUnread && isParticipatingThread(marker, threadsStats)) {
const isMuted = mutedChannelIds?.has(marker.channelId) || mutedChannelIds?.has(spaceId);
if (!isMuted) {
results[spaceId].mentions += marker.mentions;
results[spaceId].isUnread = true;
// dismiss threads when marking channels as unread
if (!marker.threadParentId) {
results[spaceId].unreadChannelIds.add(marker.channelId);
}
}
}
}
});
Object.entries(results).forEach(([spaceId, { isUnread, mentions, unreadChannelIds }]) => {
next = updateState(spaceId, isUnread, mentions, unreadChannelIds, next);
});
return next;
}
const isParticipatingThread = (marker, threadStats) => {
// if the thread has no parent, then it's a channel we're participating in
if (!marker.threadParentId) {
return true;
}
const thread = threadStats[marker.channelId]?.[marker.threadParentId];
return thread?.isParticipating;
};
//# sourceMappingURL=spaceUnreadsTransform.js.map