Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: remove stale subscriber count logic and types refactor #2832

Merged
merged 8 commits into from
Dec 6, 2024
10 changes: 8 additions & 2 deletions package/src/components/Message/Message.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,15 @@ export type MessagePropsWithContext<
> = Pick<ChannelContextValue<StreamChatGenerics>, 'channel' | 'enforceUniqueReaction' | 'members'> &
Pick<KeyboardContextValue, 'dismissKeyboard'> &
Partial<
Omit<MessageContextValue<StreamChatGenerics>, 'groupStyles' | 'handleReaction' | 'message' | 'isMessageAIGenerated'>
Omit<
MessageContextValue<StreamChatGenerics>,
'groupStyles' | 'handleReaction' | 'message' | 'isMessageAIGenerated'
>
> &
Pick<
MessageContextValue<StreamChatGenerics>,
'groupStyles' | 'message' | 'isMessageAIGenerated'
> &
Pick<MessageContextValue<StreamChatGenerics>, 'groupStyles' | 'message' | 'isMessageAIGenerated'> &
Pick<
MessagesContextValue<StreamChatGenerics>,
| 'sendReaction'
Expand Down
7 changes: 2 additions & 5 deletions package/src/components/MessageList/hooks/useMessageList.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import type { ChannelState, MessageResponse } from 'stream-chat';

import {
ChannelContextValue,
useChannelContext,
} from '../../../contexts/channelContext/ChannelContext';
import { useChannelContext } from '../../../contexts/channelContext/ChannelContext';
import { useChatContext } from '../../../contexts/chatContext/ChatContext';
import {
DeletedMessagesVisibilityType,
Expand Down Expand Up @@ -61,7 +58,7 @@ export const useMessageList = <
const { threadMessages } = useThreadContext<StreamChatGenerics>();

const messageList = threadList ? threadMessages : messages;
const readList: ChannelContextValue<StreamChatGenerics>['read'] | undefined = threadList
const readList: ChannelState<StreamChatGenerics>['read'] | undefined = threadList
? undefined
: read;

Expand Down
5 changes: 3 additions & 2 deletions package/src/components/MessageList/utils/getReadStates.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ChannelContextValue } from '../../../contexts/channelContext/ChannelContext';
import { ChannelState } from 'stream-chat';

import type { PaginatedMessageListContextValue } from '../../../contexts/paginatedMessageListContext/PaginatedMessageListContext';
import type { ThreadContextValue } from '../../../contexts/threadContext/ThreadContext';
import type { DefaultStreamChatGenerics } from '../../../types/types';
Expand All @@ -10,7 +11,7 @@ export const getReadStates = <
messages:
| PaginatedMessageListContextValue<StreamChatGenerics>['messages']
| ThreadContextValue<StreamChatGenerics>['threadMessages'],
read?: ChannelContextValue<StreamChatGenerics>['read'],
read?: ChannelState<StreamChatGenerics>['read'],
) => {
const readData: Record<string, number> = {};

Expand Down
70 changes: 7 additions & 63 deletions package/src/contexts/channelsStateContext/ChannelsStateContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import React, {
useRef,
} from 'react';

import { ChannelState as StreamChannelState } from 'stream-chat';

import type { DefaultStreamChatGenerics } from '../../types/types';
import { ActiveChannelsProvider } from '../activeChannelsRefContext/ActiveChannelsRefContext';

import type { ChannelContextValue } from '../channelContext/ChannelContext';
import type { PaginatedMessageListContextValue } from '../paginatedMessageListContext/PaginatedMessageListContext';
import type { ThreadContextValue } from '../threadContext/ThreadContext';
import type { TypingContextValue } from '../typingContext/TypingContext';
Expand All @@ -22,14 +23,13 @@ import { isTestEnvironment } from '../utils/isTestEnvironment';
export type ChannelState<
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
> = {
members: ChannelContextValue<StreamChatGenerics>['members'];
members: StreamChannelState<StreamChatGenerics>['members'];
messages: PaginatedMessageListContextValue<StreamChatGenerics>['messages'];
read: ChannelContextValue<StreamChatGenerics>['read'];
subscriberCount: number;
read: StreamChannelState<StreamChatGenerics>['read'];
threadMessages: ThreadContextValue<StreamChatGenerics>['threadMessages'];
typing: TypingContextValue<StreamChatGenerics>['typing'];
watcherCount: ChannelContextValue<StreamChatGenerics>['watcherCount'];
watchers: ChannelContextValue<StreamChatGenerics>['watchers'];
watcherCount: number;
watchers: StreamChannelState<StreamChatGenerics>['watchers'];
};

type ChannelsState<
Expand All @@ -56,25 +56,12 @@ type SetStateAction<
type: 'SET_STATE';
};

type IncreaseSubscriberCountAction = {
payload: { cid: string };
type: 'INCREASE_SUBSCRIBER_COUNT';
};
type DecreaseSubscriberCountAction = {
payload: { cid: string };
type: 'DECREASE_SUBSCRIBER_COUNT';
};

type Action<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> =
| SetStateAction<StreamChatGenerics>
| IncreaseSubscriberCountAction
| DecreaseSubscriberCountAction;
SetStateAction<StreamChatGenerics>;

export type ChannelsStateContextValue<
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
> = {
decreaseSubscriberCount: (value: { cid: string }) => void;
increaseSubscriberCount: (value: { cid: string }) => void;
setState: (value: Payload<Keys, StreamChatGenerics>) => void;
state: ChannelsState<StreamChatGenerics>;
};
Expand All @@ -95,39 +82,6 @@ function reducer(state: ChannelsState, action: Action) {
},
};

case 'INCREASE_SUBSCRIBER_COUNT': {
const currentCount = state[action.payload.cid]?.subscriberCount ?? 0;
return {
...state,
[action.payload.cid]: {
...(state[action.payload.cid] || {}),
subscriberCount: currentCount + 1,
},
};
}

case 'DECREASE_SUBSCRIBER_COUNT': {
const currentCount = state[action.payload.cid]?.subscriberCount ?? 0;

// If there last subscribed Channel component unsubscribes, we clear the channel state.
if (currentCount <= 1) {
const stateShallowCopy = {
...state,
};

delete stateShallowCopy[action.payload.cid];

return stateShallowCopy;
}

return {
...state,
[action.payload.cid]: {
...(state[action.payload.cid] || {}),
subscriberCount: currentCount - 1,
},
};
}
default:
throw new Error();
}
Expand All @@ -150,18 +104,8 @@ export const ChannelsStateProvider = <
dispatch({ payload, type: 'SET_STATE' });
}, []);

const increaseSubscriberCount = useCallback((payload: { cid: string }) => {
dispatch({ payload, type: 'INCREASE_SUBSCRIBER_COUNT' });
}, []);

const decreaseSubscriberCount = useCallback((payload: { cid: string }) => {
dispatch({ payload, type: 'DECREASE_SUBSCRIBER_COUNT' });
}, []);

const value = useMemo(
() => ({
decreaseSubscriberCount,
increaseSubscriberCount,
setState,
state,
}),
Expand Down
31 changes: 5 additions & 26 deletions package/src/contexts/channelsStateContext/useChannelState.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useMemo } from 'react';
import { useCallback, useMemo } from 'react';

import type { Channel as ChannelType } from 'stream-chat';

Expand All @@ -11,15 +11,12 @@ import type { DefaultStreamChatGenerics } from '../../types/types';
type StateManagerParams<
Key extends Keys,
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
> = Omit<
ChannelsStateContextValue<StreamChatGenerics>,
'increaseSubscriberCount' | 'decreaseSubscriberCount'
> & {
> = ChannelsStateContextValue<StreamChatGenerics> & {
cid: string;
key: Key;
};

/*
/*
This hook takes care of creating a useState-like interface which can be used later to call
updates to the ChannelsStateContext reducer. It receives the cid and key which it wants to update
and perform the state updates. Also supports a initialState.
Expand All @@ -28,15 +25,7 @@ function useStateManager<
Key extends Keys,
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
>(
{
cid,
key,
setState,
state,
}: Omit<
StateManagerParams<Key, StreamChatGenerics>,
'increaseSubscriberCount' | 'decreaseSubscriberCount'
>,
{ cid, key, setState, state }: StateManagerParams<Key, StreamChatGenerics>,
initialValue?: ChannelState<StreamChatGenerics>[Key],
) {
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down Expand Up @@ -79,17 +68,7 @@ export function useChannelState<
threadId?: string,
): UseChannelStateValue<StreamChatGenerics> {
const cid = channel?.id || 'id'; // in case channel is not initialized, use generic id string for indexing
const { decreaseSubscriberCount, increaseSubscriberCount, setState, state } =
useChannelsStateContext<StreamChatGenerics>();

// Keeps track of how many Channel components are subscribed to this Channel state (Channel vs Thread concurrency)
useEffect(() => {
increaseSubscriberCount({ cid });
return () => {
decreaseSubscriberCount({ cid });
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const { setState, state } = useChannelsStateContext<StreamChatGenerics>();

const [members, setMembers] = useStateManager(
{
Expand Down
Loading