-
Notifications
You must be signed in to change notification settings - Fork 305
/
PaginatedMessageListContext.tsx
113 lines (102 loc) · 3.6 KB
/
PaginatedMessageListContext.tsx
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import React, { PropsWithChildren, useContext } from 'react';
import type { ChannelState } from 'stream-chat';
import type { DefaultStreamChatGenerics, UnknownType } from '../../types/types';
import { DEFAULT_BASE_CONTEXT_VALUE } from '../utils/defaultBaseContextValue';
import { getDisplayName } from '../utils/getDisplayName';
import { isTestEnvironment } from '../utils/isTestEnvironment';
export type PaginatedMessageListContextValue<
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
> = {
/**
* Has more messages to load
*/
hasMore: boolean;
/**
* Flag to indicate that are no more recent messages to be loaded
*/
hasNoMoreRecentMessagesToLoad: boolean;
/**
* Is loading more messages
*/
loadingMore: boolean;
/**
* Is loading more recent messages
*/
loadingMoreRecent: boolean;
/**
* Load more messages
*/
loadMore: (limit?: number) => Promise<void>;
/**
* Load more recent messages
*/
loadMoreRecent: (limit?: number) => Promise<void>;
/**
* Messages from client state
*/
messages: ChannelState<StreamChatGenerics>['messages'];
/**
* Set loadingMore
*/
setLoadingMore: React.Dispatch<React.SetStateAction<boolean>>;
/**
* Set loadingMoreRecent
*/
setLoadingMoreRecent: React.Dispatch<React.SetStateAction<boolean>>;
};
export const PaginatedMessageListContext = React.createContext(
DEFAULT_BASE_CONTEXT_VALUE as PaginatedMessageListContextValue,
);
export const PaginatedMessageListProvider = <
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
>({
children,
value,
}: PropsWithChildren<{
value?: PaginatedMessageListContextValue<StreamChatGenerics>;
}>) => (
<PaginatedMessageListContext.Provider
value={value as unknown as PaginatedMessageListContextValue}
>
{children}
</PaginatedMessageListContext.Provider>
);
export const usePaginatedMessageListContext = <
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
>() => {
const contextValue = useContext(
PaginatedMessageListContext,
) as unknown as PaginatedMessageListContextValue<StreamChatGenerics>;
if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) {
throw new Error(
`The usePaginatedMessageListContext hook was called outside of the PaginatedMessageList provider. Make sure you have configured Channel component correctly - https://getstream.io/chat/docs/sdk/reactnative/basics/hello_stream_chat/#channel`,
);
}
return contextValue;
};
/**
* @deprecated
*
* This will be removed in the next major version.
*
* Typescript currently does not support partial inference so if ChatContext
* typing is desired while using the HOC withPaginatedMessageListContext the Props for the
* wrapped component must be provided as the first generic.
*/
export const withPaginatedMessageListContext = <
P extends UnknownType,
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
>(
Component: React.ComponentType<P>,
): React.ComponentType<Omit<P, keyof PaginatedMessageListContextValue<StreamChatGenerics>>> => {
const WithPaginatedMessageListContextComponent = (
props: Omit<P, keyof PaginatedMessageListContextValue<StreamChatGenerics>>,
) => {
const paginatedMessageListContext = usePaginatedMessageListContext<StreamChatGenerics>();
return <Component {...(props as P)} {...paginatedMessageListContext} />;
};
WithPaginatedMessageListContextComponent.displayName = `WithPaginatedMessageListContext${getDisplayName(
Component,
)}`;
return WithPaginatedMessageListContextComponent;
};