stream-chat-react-native-core 9.3.1-beta.3 → 9.3.1-beta.5
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/lib/commonjs/components/Message/MessageItemView/MessageBubble.js +2 -3
- package/lib/commonjs/components/Message/MessageItemView/MessageBubble.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/MessageContent.js +22 -29
- package/lib/commonjs/components/Message/MessageItemView/MessageContent.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/MessageWrapper.js +2 -3
- package/lib/commonjs/components/Message/MessageItemView/MessageWrapper.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/utils/renderText.js +24 -0
- package/lib/commonjs/components/Message/MessageItemView/utils/renderText.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useMessageDeliveryData.js +10 -5
- package/lib/commonjs/components/Message/hooks/useMessageDeliveryData.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useMessageReadData.js +10 -5
- package/lib/commonjs/components/Message/hooks/useMessageReadData.js.map +1 -1
- package/lib/commonjs/components/Poll/Poll.js +21 -1
- package/lib/commonjs/components/Poll/Poll.js.map +1 -1
- package/lib/commonjs/components/Poll/components/PollButtons.js +39 -55
- package/lib/commonjs/components/Poll/components/PollButtons.js.map +1 -1
- package/lib/commonjs/components/Poll/components/PollOption.js +6 -19
- package/lib/commonjs/components/Poll/components/PollOption.js.map +1 -1
- package/lib/commonjs/components/Poll/contexts/PollUIStateContext.js +147 -0
- package/lib/commonjs/components/Poll/contexts/PollUIStateContext.js.map +1 -0
- package/lib/commonjs/components/Poll/contexts/index.js +15 -0
- package/lib/commonjs/components/Poll/contexts/index.js.map +1 -0
- package/lib/commonjs/components/Poll/hooks/useEndVote.js +48 -0
- package/lib/commonjs/components/Poll/hooks/useEndVote.js.map +1 -0
- package/lib/commonjs/components/Poll/hooks/usePollAccessibilityActions.js +153 -0
- package/lib/commonjs/components/Poll/hooks/usePollAccessibilityActions.js.map +1 -0
- package/lib/commonjs/components/Poll/hooks/usePollAccessibilityLabel.js +64 -0
- package/lib/commonjs/components/Poll/hooks/usePollAccessibilityLabel.js.map +1 -0
- package/lib/commonjs/components/Poll/hooks/usePollState.js +2 -35
- package/lib/commonjs/components/Poll/hooks/usePollState.js.map +1 -1
- package/lib/commonjs/components/Poll/hooks/usePollVoteToggle.js +41 -0
- package/lib/commonjs/components/Poll/hooks/usePollVoteToggle.js.map +1 -0
- package/lib/commonjs/components/UIComponents/BottomSheetModal.js +40 -0
- package/lib/commonjs/components/UIComponents/BottomSheetModal.js.map +1 -1
- package/lib/commonjs/contexts/overlayContext/MessageOverlayHostLayer.js +15 -0
- package/lib/commonjs/contexts/overlayContext/MessageOverlayHostLayer.js.map +1 -1
- package/lib/commonjs/i18n/ar.json +9 -1
- package/lib/commonjs/i18n/en.json +8 -0
- package/lib/commonjs/i18n/es.json +9 -1
- package/lib/commonjs/i18n/fr.json +9 -1
- package/lib/commonjs/i18n/he.json +9 -1
- package/lib/commonjs/i18n/hi.json +9 -1
- package/lib/commonjs/i18n/it.json +9 -1
- package/lib/commonjs/i18n/ja.json +9 -1
- package/lib/commonjs/i18n/ko.json +9 -1
- package/lib/commonjs/i18n/nl.json +9 -1
- package/lib/commonjs/i18n/pt-br.json +9 -1
- package/lib/commonjs/i18n/ru.json +9 -1
- package/lib/commonjs/i18n/tr.json +9 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Message/MessageItemView/MessageBubble.js +2 -3
- package/lib/module/components/Message/MessageItemView/MessageBubble.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/MessageContent.js +22 -29
- package/lib/module/components/Message/MessageItemView/MessageContent.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/MessageWrapper.js +2 -3
- package/lib/module/components/Message/MessageItemView/MessageWrapper.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/utils/renderText.js +24 -0
- package/lib/module/components/Message/MessageItemView/utils/renderText.js.map +1 -1
- package/lib/module/components/Message/hooks/useMessageDeliveryData.js +10 -5
- package/lib/module/components/Message/hooks/useMessageDeliveryData.js.map +1 -1
- package/lib/module/components/Message/hooks/useMessageReadData.js +10 -5
- package/lib/module/components/Message/hooks/useMessageReadData.js.map +1 -1
- package/lib/module/components/Poll/Poll.js +21 -1
- package/lib/module/components/Poll/Poll.js.map +1 -1
- package/lib/module/components/Poll/components/PollButtons.js +39 -55
- package/lib/module/components/Poll/components/PollButtons.js.map +1 -1
- package/lib/module/components/Poll/components/PollOption.js +6 -19
- package/lib/module/components/Poll/components/PollOption.js.map +1 -1
- package/lib/module/components/Poll/contexts/PollUIStateContext.js +147 -0
- package/lib/module/components/Poll/contexts/PollUIStateContext.js.map +1 -0
- package/lib/module/components/Poll/contexts/index.js +15 -0
- package/lib/module/components/Poll/contexts/index.js.map +1 -0
- package/lib/module/components/Poll/hooks/useEndVote.js +48 -0
- package/lib/module/components/Poll/hooks/useEndVote.js.map +1 -0
- package/lib/module/components/Poll/hooks/usePollAccessibilityActions.js +153 -0
- package/lib/module/components/Poll/hooks/usePollAccessibilityActions.js.map +1 -0
- package/lib/module/components/Poll/hooks/usePollAccessibilityLabel.js +64 -0
- package/lib/module/components/Poll/hooks/usePollAccessibilityLabel.js.map +1 -0
- package/lib/module/components/Poll/hooks/usePollState.js +2 -35
- package/lib/module/components/Poll/hooks/usePollState.js.map +1 -1
- package/lib/module/components/Poll/hooks/usePollVoteToggle.js +41 -0
- package/lib/module/components/Poll/hooks/usePollVoteToggle.js.map +1 -0
- package/lib/module/components/UIComponents/BottomSheetModal.js +40 -0
- package/lib/module/components/UIComponents/BottomSheetModal.js.map +1 -1
- package/lib/module/contexts/overlayContext/MessageOverlayHostLayer.js +15 -0
- package/lib/module/contexts/overlayContext/MessageOverlayHostLayer.js.map +1 -1
- package/lib/module/i18n/ar.json +9 -1
- package/lib/module/i18n/en.json +8 -0
- package/lib/module/i18n/es.json +9 -1
- package/lib/module/i18n/fr.json +9 -1
- package/lib/module/i18n/he.json +9 -1
- package/lib/module/i18n/hi.json +9 -1
- package/lib/module/i18n/it.json +9 -1
- package/lib/module/i18n/ja.json +9 -1
- package/lib/module/i18n/ko.json +9 -1
- package/lib/module/i18n/nl.json +9 -1
- package/lib/module/i18n/pt-br.json +9 -1
- package/lib/module/i18n/ru.json +9 -1
- package/lib/module/i18n/tr.json +9 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageBubble.d.ts +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageBubble.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageContent.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageWrapper.d.ts +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageWrapper.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/utils/renderText.d.ts.map +1 -1
- package/lib/typescript/components/Message/hooks/useMessageDeliveryData.d.ts.map +1 -1
- package/lib/typescript/components/Message/hooks/useMessageReadData.d.ts.map +1 -1
- package/lib/typescript/components/Poll/Poll.d.ts.map +1 -1
- package/lib/typescript/components/Poll/components/PollButtons.d.ts.map +1 -1
- package/lib/typescript/components/Poll/components/PollOption.d.ts.map +1 -1
- package/lib/typescript/components/Poll/contexts/PollUIStateContext.d.ts +31 -0
- package/lib/typescript/components/Poll/contexts/PollUIStateContext.d.ts.map +1 -0
- package/lib/typescript/components/Poll/contexts/index.d.ts +2 -0
- package/lib/typescript/components/Poll/contexts/index.d.ts.map +1 -0
- package/lib/typescript/components/Poll/hooks/useEndVote.d.ts +7 -0
- package/lib/typescript/components/Poll/hooks/useEndVote.d.ts.map +1 -0
- package/lib/typescript/components/Poll/hooks/usePollAccessibilityActions.d.ts +25 -0
- package/lib/typescript/components/Poll/hooks/usePollAccessibilityActions.d.ts.map +1 -0
- package/lib/typescript/components/Poll/hooks/usePollAccessibilityLabel.d.ts +8 -0
- package/lib/typescript/components/Poll/hooks/usePollAccessibilityLabel.d.ts.map +1 -0
- package/lib/typescript/components/Poll/hooks/usePollState.d.ts.map +1 -1
- package/lib/typescript/components/Poll/hooks/usePollVoteToggle.d.ts +8 -0
- package/lib/typescript/components/Poll/hooks/usePollVoteToggle.d.ts.map +1 -0
- package/lib/typescript/components/UIComponents/BottomSheetModal.d.ts.map +1 -1
- package/lib/typescript/contexts/overlayContext/MessageOverlayHostLayer.d.ts.map +1 -1
- package/lib/typescript/i18n/ar.json +9 -1
- package/lib/typescript/i18n/en.json +8 -0
- package/lib/typescript/i18n/es.json +9 -1
- package/lib/typescript/i18n/fr.json +9 -1
- package/lib/typescript/i18n/he.json +9 -1
- package/lib/typescript/i18n/hi.json +9 -1
- package/lib/typescript/i18n/it.json +9 -1
- package/lib/typescript/i18n/ja.json +9 -1
- package/lib/typescript/i18n/ko.json +9 -1
- package/lib/typescript/i18n/nl.json +9 -1
- package/lib/typescript/i18n/pt-br.json +9 -1
- package/lib/typescript/i18n/ru.json +9 -1
- package/lib/typescript/i18n/tr.json +9 -1
- package/lib/typescript/utils/i18n/Streami18n.d.ts +8 -0
- package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/Message/MessageItemView/MessageBubble.tsx +3 -1
- package/src/components/Message/MessageItemView/MessageContent.tsx +36 -36
- package/src/components/Message/MessageItemView/MessageWrapper.tsx +1 -1
- package/src/components/Message/MessageItemView/utils/renderText.tsx +31 -0
- package/src/components/Message/hooks/useMessageDeliveryData.ts +11 -6
- package/src/components/Message/hooks/useMessageReadData.ts +11 -6
- package/src/components/Poll/Poll.tsx +29 -2
- package/src/components/Poll/components/PollButtons.tsx +37 -44
- package/src/components/Poll/components/PollOption.tsx +4 -13
- package/src/components/Poll/contexts/PollUIStateContext.tsx +105 -0
- package/src/components/Poll/contexts/index.ts +1 -0
- package/src/components/Poll/hooks/__tests__/usePollAccessibilityActions.test.tsx +358 -0
- package/src/components/Poll/hooks/__tests__/usePollAccessibilityLabel.test.tsx +142 -0
- package/src/components/Poll/hooks/useEndVote.ts +37 -0
- package/src/components/Poll/hooks/usePollAccessibilityActions.ts +191 -0
- package/src/components/Poll/hooks/usePollAccessibilityLabel.ts +75 -0
- package/src/components/Poll/hooks/usePollState.ts +3 -26
- package/src/components/Poll/hooks/usePollVoteToggle.ts +34 -0
- package/src/components/Thread/__tests__/__snapshots__/Thread.test.tsx.snap +4 -4
- package/src/components/UIComponents/BottomSheetModal.tsx +44 -1
- package/src/contexts/overlayContext/MessageOverlayHostLayer.tsx +17 -1
- package/src/i18n/ar.json +9 -1
- package/src/i18n/en.json +8 -0
- package/src/i18n/es.json +9 -1
- package/src/i18n/fr.json +9 -1
- package/src/i18n/he.json +9 -1
- package/src/i18n/hi.json +9 -1
- package/src/i18n/it.json +9 -1
- package/src/i18n/ja.json +9 -1
- package/src/i18n/ko.json +9 -1
- package/src/i18n/nl.json +9 -1
- package/src/i18n/pt-br.json +9 -1
- package/src/i18n/ru.json +9 -1
- package/src/i18n/tr.json +9 -1
- package/src/version.json +1 -1
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Event, LocalMessage, UserResponse } from 'stream-chat';
|
|
4
4
|
|
|
5
5
|
import { useChannelContext } from '../../../contexts/channelContext/ChannelContext';
|
|
6
6
|
import { useChatContext } from '../../../contexts/chatContext/ChatContext';
|
|
7
|
+
import { useStableCallback } from '../../../hooks';
|
|
7
8
|
|
|
8
9
|
export const useMessageDeliveredData = ({ message }: { message?: LocalMessage }) => {
|
|
9
10
|
const { channel } = useChannelContext();
|
|
10
11
|
const { client } = useChatContext();
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
const messageIdRef = useRef<string>(message?.id);
|
|
14
|
+
|
|
15
|
+
const calculate = useStableCallback(() => {
|
|
12
16
|
if (!message?.created_at) {
|
|
13
17
|
return [];
|
|
14
18
|
}
|
|
@@ -17,13 +21,14 @@ export const useMessageDeliveredData = ({ message }: { message?: LocalMessage })
|
|
|
17
21
|
timestampMs: new Date(message.created_at).getTime(),
|
|
18
22
|
};
|
|
19
23
|
return channel.messageReceiptsTracker.deliveredForMessage(messageRef);
|
|
20
|
-
}
|
|
24
|
+
});
|
|
21
25
|
|
|
22
|
-
const [deliveredTo, setDeliveredTo] = useState<UserResponse[]>(
|
|
26
|
+
const [deliveredTo, setDeliveredTo] = useState<UserResponse[]>(() => calculate());
|
|
23
27
|
|
|
24
|
-
|
|
28
|
+
if (!!messageIdRef.current && !!message?.id && messageIdRef.current !== message.id) {
|
|
25
29
|
setDeliveredTo(calculate());
|
|
26
|
-
|
|
30
|
+
messageIdRef.current = message.id;
|
|
31
|
+
}
|
|
27
32
|
|
|
28
33
|
useEffect(() => {
|
|
29
34
|
const { unsubscribe } = channel.on('message.delivered', (event: Event) => {
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
2
|
|
|
3
3
|
import { Event, LocalMessage, UserResponse } from 'stream-chat';
|
|
4
4
|
|
|
5
5
|
import { useChannelContext } from '../../../contexts/channelContext/ChannelContext';
|
|
6
6
|
import { useChatContext } from '../../../contexts/chatContext/ChatContext';
|
|
7
|
+
import { useStableCallback } from '../../../hooks';
|
|
7
8
|
|
|
8
9
|
export const useMessageReadData = ({ message }: { message?: LocalMessage }) => {
|
|
9
10
|
const { channel } = useChannelContext();
|
|
10
11
|
const { client } = useChatContext();
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
const messageIdRef = useRef<string>(message?.id);
|
|
14
|
+
|
|
15
|
+
const calculate = useStableCallback(() => {
|
|
12
16
|
if (!message?.created_at) {
|
|
13
17
|
return [];
|
|
14
18
|
}
|
|
@@ -18,13 +22,14 @@ export const useMessageReadData = ({ message }: { message?: LocalMessage }) => {
|
|
|
18
22
|
};
|
|
19
23
|
|
|
20
24
|
return channel.messageReceiptsTracker.readersForMessage(messageRef);
|
|
21
|
-
}
|
|
25
|
+
});
|
|
22
26
|
|
|
23
|
-
const [readBy, setReadBy] = useState<UserResponse[]>(
|
|
27
|
+
const [readBy, setReadBy] = useState<UserResponse[]>(() => calculate());
|
|
24
28
|
|
|
25
|
-
|
|
29
|
+
if (!!messageIdRef.current && !!message?.id && messageIdRef.current !== message.id) {
|
|
26
30
|
setReadBy(calculate());
|
|
27
|
-
|
|
31
|
+
messageIdRef.current = message.id;
|
|
32
|
+
}
|
|
28
33
|
|
|
29
34
|
useEffect(() => {
|
|
30
35
|
const { unsubscribe } = channel.on('message.read', (event: Event) => {
|
|
@@ -4,15 +4,20 @@ import { StyleSheet, Text, View } from 'react-native';
|
|
|
4
4
|
import { PollOption as PollOptionClass } from 'stream-chat';
|
|
5
5
|
|
|
6
6
|
import { PollOption, ShowAllOptionsButton } from './components';
|
|
7
|
+
import { PollUIStateProvider } from './contexts/PollUIStateContext';
|
|
7
8
|
|
|
9
|
+
import { usePollAccessibilityActions } from './hooks/usePollAccessibilityActions';
|
|
10
|
+
import { usePollAccessibilityLabel } from './hooks/usePollAccessibilityLabel';
|
|
8
11
|
import { usePollState } from './hooks/usePollState';
|
|
9
12
|
|
|
13
|
+
import { useA11yLabel } from '../../a11y/hooks/useA11yLabel';
|
|
10
14
|
import {
|
|
11
15
|
PollContextProvider,
|
|
12
16
|
PollContextValue,
|
|
13
17
|
useTheme,
|
|
14
18
|
useTranslationContext,
|
|
15
19
|
} from '../../contexts';
|
|
20
|
+
import { useAccessibilityContext } from '../../contexts/accessibilityContext/AccessibilityContext';
|
|
16
21
|
import { useComponentsContext } from '../../contexts/componentsContext/ComponentsContext';
|
|
17
22
|
|
|
18
23
|
import { primitives } from '../../theme';
|
|
@@ -61,6 +66,10 @@ export const PollContent = () => {
|
|
|
61
66
|
const styles = useStyles();
|
|
62
67
|
const { PollButtons: PollButtonsComponent, PollHeader: PollHeaderComponent } =
|
|
63
68
|
useComponentsContext();
|
|
69
|
+
const { enabled: a11yEnabled } = useAccessibilityContext();
|
|
70
|
+
const accessibilityHint = useA11yLabel('a11y/Double tap and hold to activate contextual menu');
|
|
71
|
+
const accessibilityLabel = usePollAccessibilityLabel();
|
|
72
|
+
const { accessibilityActions, onAccessibilityAction } = usePollAccessibilityActions();
|
|
64
73
|
|
|
65
74
|
const {
|
|
66
75
|
theme: {
|
|
@@ -70,8 +79,24 @@ export const PollContent = () => {
|
|
|
70
79
|
},
|
|
71
80
|
} = useTheme();
|
|
72
81
|
|
|
82
|
+
// NOTE: Android custom accessibilityActions are broken in RN < 0.83.2 —
|
|
83
|
+
// see facebook/react-native#47268, fixed by PR #52724. On affected versions
|
|
84
|
+
// the actions menu surfaces only a subset of the list and dispatch
|
|
85
|
+
// announces "Action not supported". iOS works correctly on all versions.
|
|
86
|
+
// Once the SDK's minimum RN reaches 0.83.2, wrap the descendants below in
|
|
87
|
+
// <View importantForAccessibility='no-hide-descendants'> so Android
|
|
88
|
+
// TalkBack groups them under the composite rather than exposing each
|
|
89
|
+
// interactive child as a separate focus stop.
|
|
73
90
|
return (
|
|
74
|
-
<View
|
|
91
|
+
<View
|
|
92
|
+
accessibilityActions={accessibilityActions}
|
|
93
|
+
accessibilityHint={accessibilityHint}
|
|
94
|
+
accessibilityLabel={accessibilityLabel}
|
|
95
|
+
accessibilityRole={a11yEnabled ? 'button' : undefined}
|
|
96
|
+
accessible={a11yEnabled || undefined}
|
|
97
|
+
onAccessibilityAction={onAccessibilityAction}
|
|
98
|
+
style={[styles.container, container]}
|
|
99
|
+
>
|
|
75
100
|
<PollHeaderComponent />
|
|
76
101
|
<View style={[styles.optionsWrapper, optionsWrapper]}>
|
|
77
102
|
{options?.slice(0, defaultPollOptionCount)?.map((option: PollOptionClass) => (
|
|
@@ -93,7 +118,9 @@ export const Poll = ({ message, poll }: PollProps) => {
|
|
|
93
118
|
poll,
|
|
94
119
|
}}
|
|
95
120
|
>
|
|
96
|
-
|
|
121
|
+
<PollUIStateProvider>
|
|
122
|
+
{PollContentOverride ? <PollContentOverride /> : <PollContent />}
|
|
123
|
+
</PollUIStateProvider>
|
|
97
124
|
</PollContextProvider>
|
|
98
125
|
);
|
|
99
126
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useMemo
|
|
1
|
+
import React, { useCallback, useMemo } from 'react';
|
|
2
2
|
import { Modal, StyleSheet, View } from 'react-native';
|
|
3
3
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
4
4
|
|
|
@@ -13,13 +13,22 @@ import { useChatContext, usePollContext, useTheme, useTranslationContext } from
|
|
|
13
13
|
import { primitives } from '../../../theme';
|
|
14
14
|
import { defaultPollOptionCount } from '../../../utils/constants';
|
|
15
15
|
import { SafeAreaViewWrapper } from '../../UIComponents/SafeAreaViewWrapper';
|
|
16
|
+
import {
|
|
17
|
+
useAddCommentOpen,
|
|
18
|
+
useAllCommentsOpen,
|
|
19
|
+
useAllOptionsOpen,
|
|
20
|
+
usePollUIStateContext,
|
|
21
|
+
useSuggestOptionOpen,
|
|
22
|
+
useViewResultsOpen,
|
|
23
|
+
} from '../contexts/PollUIStateContext';
|
|
16
24
|
import { useIsPollCreatedByCurrentUser } from '../hook/useIsPollCreatedByCurrentUser';
|
|
17
25
|
import { usePollState } from '../hooks/usePollState';
|
|
18
26
|
|
|
19
27
|
export const ViewResultsButton = (props: PollButtonProps) => {
|
|
20
28
|
const { t } = useTranslationContext();
|
|
21
29
|
const { message, poll } = usePollContext();
|
|
22
|
-
const
|
|
30
|
+
const { closeViewResults, openViewResults } = usePollUIStateContext();
|
|
31
|
+
const showResults = useViewResultsOpen();
|
|
23
32
|
const { onPress } = props;
|
|
24
33
|
|
|
25
34
|
const onPressHandler = useCallback(() => {
|
|
@@ -28,15 +37,11 @@ export const ViewResultsButton = (props: PollButtonProps) => {
|
|
|
28
37
|
return;
|
|
29
38
|
}
|
|
30
39
|
|
|
31
|
-
|
|
32
|
-
}, [message, onPress, poll]);
|
|
40
|
+
openViewResults();
|
|
41
|
+
}, [message, onPress, openViewResults, poll]);
|
|
33
42
|
|
|
34
43
|
const styles = useStyles();
|
|
35
44
|
|
|
36
|
-
const onRequestClose = useCallback(() => {
|
|
37
|
-
setShowResults(false);
|
|
38
|
-
}, []);
|
|
39
|
-
|
|
40
45
|
return (
|
|
41
46
|
<>
|
|
42
47
|
<GenericPollButton
|
|
@@ -46,10 +51,10 @@ export const ViewResultsButton = (props: PollButtonProps) => {
|
|
|
46
51
|
type='outline'
|
|
47
52
|
/>
|
|
48
53
|
{showResults ? (
|
|
49
|
-
<Modal animationType='slide' onRequestClose={
|
|
54
|
+
<Modal animationType='slide' onRequestClose={closeViewResults} visible={showResults}>
|
|
50
55
|
<GestureHandlerRootView style={styles.modalRoot}>
|
|
51
56
|
<SafeAreaViewWrapper style={styles.safeArea}>
|
|
52
|
-
<PollModalHeader onPress={
|
|
57
|
+
<PollModalHeader onPress={closeViewResults} title={t('Poll Results')} />
|
|
53
58
|
<PollResults message={message} poll={poll} />
|
|
54
59
|
</SafeAreaViewWrapper>
|
|
55
60
|
</GestureHandlerRootView>
|
|
@@ -61,7 +66,8 @@ export const ViewResultsButton = (props: PollButtonProps) => {
|
|
|
61
66
|
|
|
62
67
|
export const ShowAllOptionsButton = (props: PollButtonProps) => {
|
|
63
68
|
const { t } = useTranslationContext();
|
|
64
|
-
const
|
|
69
|
+
const { closeAllOptions, openAllOptions } = usePollUIStateContext();
|
|
70
|
+
const showAllOptions = useAllOptionsOpen();
|
|
65
71
|
const { message, poll } = usePollContext();
|
|
66
72
|
const { options } = usePollState();
|
|
67
73
|
const { onPress } = props;
|
|
@@ -72,12 +78,8 @@ export const ShowAllOptionsButton = (props: PollButtonProps) => {
|
|
|
72
78
|
return;
|
|
73
79
|
}
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
}, [message, onPress, poll]);
|
|
77
|
-
|
|
78
|
-
const onRequestClose = useCallback(() => {
|
|
79
|
-
setShowAllOptions(false);
|
|
80
|
-
}, []);
|
|
81
|
+
openAllOptions();
|
|
82
|
+
}, [message, onPress, openAllOptions, poll]);
|
|
81
83
|
|
|
82
84
|
const styles = useStyles();
|
|
83
85
|
|
|
@@ -90,10 +92,10 @@ export const ShowAllOptionsButton = (props: PollButtonProps) => {
|
|
|
90
92
|
/>
|
|
91
93
|
) : null}
|
|
92
94
|
{showAllOptions ? (
|
|
93
|
-
<Modal animationType='slide' onRequestClose={
|
|
95
|
+
<Modal animationType='slide' onRequestClose={closeAllOptions} visible={showAllOptions}>
|
|
94
96
|
<GestureHandlerRootView style={styles.modalRoot}>
|
|
95
97
|
<SafeAreaViewWrapper style={styles.safeArea}>
|
|
96
|
-
<PollModalHeader onPress={
|
|
98
|
+
<PollModalHeader onPress={closeAllOptions} title={t('Poll Options')} />
|
|
97
99
|
<PollAllOptions message={message} poll={poll} />
|
|
98
100
|
</SafeAreaViewWrapper>
|
|
99
101
|
</GestureHandlerRootView>
|
|
@@ -107,7 +109,8 @@ export const ShowAllCommentsButton = (props: PollButtonProps) => {
|
|
|
107
109
|
const { t } = useTranslationContext();
|
|
108
110
|
const { message, poll } = usePollContext();
|
|
109
111
|
const { answersCount } = usePollState();
|
|
110
|
-
const
|
|
112
|
+
const { closeAllComments, openAllComments } = usePollUIStateContext();
|
|
113
|
+
const showAnswers = useAllCommentsOpen();
|
|
111
114
|
const { onPress } = props;
|
|
112
115
|
|
|
113
116
|
const onPressHandler = useCallback(() => {
|
|
@@ -116,15 +119,11 @@ export const ShowAllCommentsButton = (props: PollButtonProps) => {
|
|
|
116
119
|
return;
|
|
117
120
|
}
|
|
118
121
|
|
|
119
|
-
|
|
120
|
-
}, [message, onPress, poll]);
|
|
122
|
+
openAllComments();
|
|
123
|
+
}, [message, onPress, openAllComments, poll]);
|
|
121
124
|
|
|
122
125
|
const styles = useStyles();
|
|
123
126
|
|
|
124
|
-
const onRequestClose = useCallback(() => {
|
|
125
|
-
setShowAnswers(false);
|
|
126
|
-
}, []);
|
|
127
|
-
|
|
128
127
|
return (
|
|
129
128
|
<>
|
|
130
129
|
{answersCount && answersCount > 0 ? (
|
|
@@ -134,10 +133,10 @@ export const ShowAllCommentsButton = (props: PollButtonProps) => {
|
|
|
134
133
|
/>
|
|
135
134
|
) : null}
|
|
136
135
|
{showAnswers ? (
|
|
137
|
-
<Modal animationType='slide' onRequestClose={
|
|
136
|
+
<Modal animationType='slide' onRequestClose={closeAllComments} visible={showAnswers}>
|
|
138
137
|
<GestureHandlerRootView style={styles.modalRoot}>
|
|
139
138
|
<SafeAreaViewWrapper style={styles.safeArea}>
|
|
140
|
-
<PollModalHeader onPress={
|
|
139
|
+
<PollModalHeader onPress={closeAllComments} title={t('Poll Comments')} />
|
|
141
140
|
<PollAnswersList message={message} poll={poll} />
|
|
142
141
|
</SafeAreaViewWrapper>
|
|
143
142
|
</GestureHandlerRootView>
|
|
@@ -151,7 +150,8 @@ export const SuggestOptionButton = (props: PollButtonProps) => {
|
|
|
151
150
|
const { t } = useTranslationContext();
|
|
152
151
|
const { message, poll } = usePollContext();
|
|
153
152
|
const { addOption, allowUserSuggestedOptions, isClosed } = usePollState();
|
|
154
|
-
const
|
|
153
|
+
const { closeSuggestOption, openSuggestOption } = usePollUIStateContext();
|
|
154
|
+
const showAddOptionDialog = useSuggestOptionOpen();
|
|
155
155
|
const { onPress } = props;
|
|
156
156
|
|
|
157
157
|
const onPressHandler = useCallback(() => {
|
|
@@ -160,12 +160,8 @@ export const SuggestOptionButton = (props: PollButtonProps) => {
|
|
|
160
160
|
return;
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
|
|
164
|
-
}, [message, onPress, poll]);
|
|
165
|
-
|
|
166
|
-
const onRequestClose = useCallback(() => {
|
|
167
|
-
setShowAddOptionDialog(false);
|
|
168
|
-
}, []);
|
|
163
|
+
openSuggestOption();
|
|
164
|
+
}, [message, onPress, openSuggestOption, poll]);
|
|
169
165
|
|
|
170
166
|
return (
|
|
171
167
|
<>
|
|
@@ -174,7 +170,7 @@ export const SuggestOptionButton = (props: PollButtonProps) => {
|
|
|
174
170
|
) : null}
|
|
175
171
|
{showAddOptionDialog ? (
|
|
176
172
|
<PollInputDialog
|
|
177
|
-
closeDialog={
|
|
173
|
+
closeDialog={closeSuggestOption}
|
|
178
174
|
onSubmit={addOption}
|
|
179
175
|
placeholder={t('Enter a new option')}
|
|
180
176
|
title={t('Suggest an option')}
|
|
@@ -189,7 +185,8 @@ export const AddCommentButton = (props: PollButtonProps) => {
|
|
|
189
185
|
const { t } = useTranslationContext();
|
|
190
186
|
const { message, poll } = usePollContext();
|
|
191
187
|
const { addComment, allowAnswers, isClosed, ownAnswer } = usePollState();
|
|
192
|
-
const
|
|
188
|
+
const { closeAddComment, openAddComment } = usePollUIStateContext();
|
|
189
|
+
const showAddCommentDialog = useAddCommentOpen();
|
|
193
190
|
const { onPress } = props;
|
|
194
191
|
|
|
195
192
|
const onPressHandler = useCallback(() => {
|
|
@@ -198,12 +195,8 @@ export const AddCommentButton = (props: PollButtonProps) => {
|
|
|
198
195
|
return;
|
|
199
196
|
}
|
|
200
197
|
|
|
201
|
-
|
|
202
|
-
}, [message, onPress, poll]);
|
|
203
|
-
|
|
204
|
-
const onRequestClose = useCallback(() => {
|
|
205
|
-
setShowAddCommentDialog(false);
|
|
206
|
-
}, []);
|
|
198
|
+
openAddComment();
|
|
199
|
+
}, [message, onPress, openAddComment, poll]);
|
|
207
200
|
|
|
208
201
|
return (
|
|
209
202
|
<>
|
|
@@ -212,7 +205,7 @@ export const AddCommentButton = (props: PollButtonProps) => {
|
|
|
212
205
|
) : null}
|
|
213
206
|
{showAddCommentDialog ? (
|
|
214
207
|
<PollInputDialog
|
|
215
|
-
closeDialog={
|
|
208
|
+
closeDialog={closeAddComment}
|
|
216
209
|
initialValue={ownAnswer?.answer_text ?? ''}
|
|
217
210
|
onSubmit={addComment}
|
|
218
211
|
placeholder={t('Your comment')}
|
|
@@ -20,11 +20,11 @@ import { useComponentsContext } from '../../../contexts/componentsContext/Compon
|
|
|
20
20
|
|
|
21
21
|
import { Check } from '../../../icons';
|
|
22
22
|
import { primitives } from '../../../theme';
|
|
23
|
-
import { useNotificationApi } from '../../Notifications';
|
|
24
23
|
import { ProgressBar } from '../../ProgressControl/ProgressBar';
|
|
25
24
|
import { UserAvatarStack } from '../../ui/Avatar/AvatarStack';
|
|
26
25
|
import { useIsPollCreatedByCurrentUser } from '../hook/useIsPollCreatedByCurrentUser';
|
|
27
26
|
import { usePollState } from '../hooks/usePollState';
|
|
27
|
+
import { usePollVoteToggle } from '../hooks/usePollVoteToggle';
|
|
28
28
|
|
|
29
29
|
const pollVoteAccessibilityStates = {
|
|
30
30
|
checked: { checked: true, selected: true },
|
|
@@ -161,7 +161,6 @@ export const PollOption = ({ option, showProgressBar = true, forceIncoming }: Po
|
|
|
161
161
|
export const VoteButton = ({ onPress, option }: PollVoteButtonProps) => {
|
|
162
162
|
const { message, poll } = usePollContext();
|
|
163
163
|
const { isClosed, ownVotesByOptionId } = usePollState();
|
|
164
|
-
const { runWithNotificationTarget } = useNotificationApi();
|
|
165
164
|
const ownCapabilities = useOwnCapabilitiesContext();
|
|
166
165
|
const {
|
|
167
166
|
theme: { semantics },
|
|
@@ -179,15 +178,7 @@ export const VoteButton = ({ onPress, option }: PollVoteButtonProps) => {
|
|
|
179
178
|
},
|
|
180
179
|
} = useTheme();
|
|
181
180
|
|
|
182
|
-
const toggleVote =
|
|
183
|
-
await runWithNotificationTarget(async () => {
|
|
184
|
-
if (ownVotesByOptionId[option.id]) {
|
|
185
|
-
await poll.removeVote(ownVotesByOptionId[option.id]?.id, message.id);
|
|
186
|
-
} else {
|
|
187
|
-
await poll.castVote(option.id, message.id);
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
}, [message.id, option.id, ownVotesByOptionId, poll, runWithNotificationTarget]);
|
|
181
|
+
const toggleVote = usePollVoteToggle();
|
|
191
182
|
|
|
192
183
|
const onPressHandler = useCallback(() => {
|
|
193
184
|
if (onPress) {
|
|
@@ -195,8 +186,8 @@ export const VoteButton = ({ onPress, option }: PollVoteButtonProps) => {
|
|
|
195
186
|
return;
|
|
196
187
|
}
|
|
197
188
|
|
|
198
|
-
toggleVote();
|
|
199
|
-
}, [message, onPress, poll, toggleVote]);
|
|
189
|
+
toggleVote(option.id);
|
|
190
|
+
}, [message, onPress, option.id, poll, toggleVote]);
|
|
200
191
|
|
|
201
192
|
const hasVote = !!ownVotesByOptionId[option.id];
|
|
202
193
|
const accessibilityState = hasVote
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import React, { PropsWithChildren, useContext, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { StateStore } from 'stream-chat';
|
|
4
|
+
|
|
5
|
+
import { DEFAULT_BASE_CONTEXT_VALUE } from '../../../contexts/utils/defaultBaseContextValue';
|
|
6
|
+
import { isTestEnvironment } from '../../../contexts/utils/isTestEnvironment';
|
|
7
|
+
import { useStateStore } from '../../../hooks/useStateStore';
|
|
8
|
+
|
|
9
|
+
export type PollUIState = {
|
|
10
|
+
addCommentOpen: boolean;
|
|
11
|
+
allCommentsOpen: boolean;
|
|
12
|
+
allOptionsOpen: boolean;
|
|
13
|
+
suggestOptionOpen: boolean;
|
|
14
|
+
viewResultsOpen: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const INITIAL_POLL_UI_STATE: PollUIState = {
|
|
18
|
+
addCommentOpen: false,
|
|
19
|
+
allCommentsOpen: false,
|
|
20
|
+
allOptionsOpen: false,
|
|
21
|
+
suggestOptionOpen: false,
|
|
22
|
+
viewResultsOpen: false,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type PollUIStateContextValue = {
|
|
26
|
+
closeAddComment: () => void;
|
|
27
|
+
closeAllComments: () => void;
|
|
28
|
+
closeAllOptions: () => void;
|
|
29
|
+
closeSuggestOption: () => void;
|
|
30
|
+
closeViewResults: () => void;
|
|
31
|
+
openAddComment: () => void;
|
|
32
|
+
openAllComments: () => void;
|
|
33
|
+
openAllOptions: () => void;
|
|
34
|
+
openSuggestOption: () => void;
|
|
35
|
+
openViewResults: () => void;
|
|
36
|
+
store: StateStore<PollUIState>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const PollUIStateContext = React.createContext(
|
|
40
|
+
DEFAULT_BASE_CONTEXT_VALUE as PollUIStateContextValue,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
export const PollUIStateProvider = ({ children }: PropsWithChildren) => {
|
|
44
|
+
const value = useState<PollUIStateContextValue>(() => {
|
|
45
|
+
const store = new StateStore<PollUIState>(INITIAL_POLL_UI_STATE);
|
|
46
|
+
return {
|
|
47
|
+
closeAddComment: () => store.partialNext({ addCommentOpen: false }),
|
|
48
|
+
closeAllComments: () => store.partialNext({ allCommentsOpen: false }),
|
|
49
|
+
closeAllOptions: () => store.partialNext({ allOptionsOpen: false }),
|
|
50
|
+
closeSuggestOption: () => store.partialNext({ suggestOptionOpen: false }),
|
|
51
|
+
closeViewResults: () => store.partialNext({ viewResultsOpen: false }),
|
|
52
|
+
openAddComment: () => store.partialNext({ addCommentOpen: true }),
|
|
53
|
+
openAllComments: () => store.partialNext({ allCommentsOpen: true }),
|
|
54
|
+
openAllOptions: () => store.partialNext({ allOptionsOpen: true }),
|
|
55
|
+
openSuggestOption: () => store.partialNext({ suggestOptionOpen: true }),
|
|
56
|
+
openViewResults: () => store.partialNext({ viewResultsOpen: true }),
|
|
57
|
+
store,
|
|
58
|
+
};
|
|
59
|
+
})[0];
|
|
60
|
+
|
|
61
|
+
return <PollUIStateContext.Provider value={value}>{children}</PollUIStateContext.Provider>;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const usePollUIStateContext = () => {
|
|
65
|
+
const contextValue = useContext(PollUIStateContext) as unknown as PollUIStateContextValue;
|
|
66
|
+
|
|
67
|
+
if (contextValue === DEFAULT_BASE_CONTEXT_VALUE && !isTestEnvironment()) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
'usePollUIStateContext must be used within a PollUIStateProvider. The provider is mounted by the Poll component automatically.',
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return contextValue;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const selectAddCommentOpen = ({ addCommentOpen }: PollUIState) => ({ addCommentOpen });
|
|
77
|
+
const selectAllCommentsOpen = ({ allCommentsOpen }: PollUIState) => ({ allCommentsOpen });
|
|
78
|
+
const selectAllOptionsOpen = ({ allOptionsOpen }: PollUIState) => ({ allOptionsOpen });
|
|
79
|
+
const selectSuggestOptionOpen = ({ suggestOptionOpen }: PollUIState) => ({ suggestOptionOpen });
|
|
80
|
+
const selectViewResultsOpen = ({ viewResultsOpen }: PollUIState) => ({ viewResultsOpen });
|
|
81
|
+
|
|
82
|
+
export const useAddCommentOpen = () => {
|
|
83
|
+
const { store } = usePollUIStateContext();
|
|
84
|
+
return useStateStore(store, selectAddCommentOpen).addCommentOpen;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const useAllCommentsOpen = () => {
|
|
88
|
+
const { store } = usePollUIStateContext();
|
|
89
|
+
return useStateStore(store, selectAllCommentsOpen).allCommentsOpen;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export const useAllOptionsOpen = () => {
|
|
93
|
+
const { store } = usePollUIStateContext();
|
|
94
|
+
return useStateStore(store, selectAllOptionsOpen).allOptionsOpen;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export const useSuggestOptionOpen = () => {
|
|
98
|
+
const { store } = usePollUIStateContext();
|
|
99
|
+
return useStateStore(store, selectSuggestOptionOpen).suggestOptionOpen;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const useViewResultsOpen = () => {
|
|
103
|
+
const { store } = usePollUIStateContext();
|
|
104
|
+
return useStateStore(store, selectViewResultsOpen).viewResultsOpen;
|
|
105
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './PollUIStateContext';
|