1- import React , { useCallback , useEffect , useState } from 'react' ;
2- import { Pressable , StyleSheet , Switch , Text , View } from 'react-native' ;
1+ import React , { useCallback , useEffect } from 'react' ;
2+ import { StyleSheet , Switch , Text , View } from 'react-native' ;
33
44import { ScrollView } from 'react-native-gesture-handler' ;
55import { useSharedValue } from 'react-native-reanimated' ;
66
77import { PollComposerState , VotingVisibility } from 'stream-chat' ;
88
9- import { CreatePollOptions , CurrentOptionPositionsCache , PollModalHeader } from './components' ;
9+ import { CreatePollOptions , CurrentOptionPositionsCache } from './components' ;
1010
11+ import { CreatePollHeader } from './components/CreatePollHeader' ;
1112import { MultipleAnswersField } from './components/MultipleAnswersField' ;
1213import { NameField } from './components/NameField' ;
1314
14- import { useCanCreatePoll } from './hooks/useCanCreatePoll' ;
15-
1615import {
1716 CreatePollContentContextValue ,
1817 CreatePollContentProvider ,
@@ -23,7 +22,6 @@ import {
2322} from '../../contexts' ;
2423import { useMessageComposer } from '../../contexts/messageInputContext/hooks/useMessageComposer' ;
2524import { useStateStore } from '../../hooks/useStateStore' ;
26- import { SendPoll } from '../../icons' ;
2725
2826const pollComposerStateSelector = ( state : PollComposerState ) => ( {
2927 allow_answers : state . data . allow_answers ,
@@ -35,127 +33,68 @@ const pollComposerStateSelector = (state: PollComposerState) => ({
3533 voting_visibility : state . data . voting_visibility ,
3634} ) ;
3735
36+ export const POLL_OPTION_HEIGHT = 71 ;
37+
3838export const CreatePollContent = ( ) => {
3939 const { t } = useTranslationContext ( ) ;
40- // const [pollOptions, setPollOptions] = useState<PollOptionData[]>([{ text: '' }]);
4140
42- const [ duplicates , setDuplicates ] = useState < string [ ] > ( [ ] ) ;
4341 const messageComposer = useMessageComposer ( ) ;
44- const canCreatePoll = useCanCreatePoll ( ) ;
4542 const { pollComposer } = messageComposer ;
4643 const { allow_answers, allow_user_suggested_options, options, voting_visibility } = useStateStore (
4744 pollComposer . state ,
4845 pollComposerStateSelector ,
4946 ) ;
5047
51- const { createPollOptionHeight, closePollCreationDialog, createAndSendPoll } =
52- useCreatePollContentContext ( ) ;
48+ const firstOption = options [ 0 ] ;
49+
50+ const { createPollOptionHeight } = useCreatePollContentContext ( ) ;
5351
5452 // positions and index lookup map
5553 // TODO: Please rethink the structure of this, bidirectional data flow is not great
5654 const currentOptionPositions = useSharedValue < CurrentOptionPositionsCache > ( {
57- inverseIndexCache : { 0 : 0 } ,
58- positionCache : { 0 : { updatedIndex : 0 , updatedTop : 0 } } ,
55+ inverseIndexCache : { 0 : firstOption . id } ,
56+ positionCache : { [ firstOption . id ] : { updatedIndex : 0 , updatedTop : 0 } } ,
5957 } ) ;
6058
6159 const {
6260 theme : {
6361 colors : { bg_user, black, white } ,
6462 poll : {
65- createContent : {
66- addComment,
67- anonymousPoll,
68- headerContainer,
69- scrollView,
70- sendButton,
71- suggestOption,
72- } ,
63+ createContent : { addComment, anonymousPoll, scrollView, suggestOption } ,
7364 } ,
7465 } ,
7566 } = useTheme ( ) ;
7667
7768 useEffect ( ( ) => {
7869 if ( ! createPollOptionHeight ) return ;
79- const newIndex = options . length ;
80- currentOptionPositions . value = {
81- inverseIndexCache : {
82- ...currentOptionPositions . value . inverseIndexCache ,
83- [ newIndex ] : newIndex ,
84- } ,
85- positionCache : {
86- ...currentOptionPositions . value . positionCache ,
87- [ newIndex ] : {
88- updatedIndex : newIndex ,
89- updatedTop : newIndex * createPollOptionHeight ,
70+ options . forEach ( ( option , index ) => {
71+ currentOptionPositions . value = {
72+ ...currentOptionPositions . value ,
73+ inverseIndexCache : {
74+ ...currentOptionPositions . value . inverseIndexCache ,
75+ [ index ] : option . id ,
9076 } ,
91- } ,
92- } ;
77+ positionCache : {
78+ ...currentOptionPositions . value . positionCache ,
79+ [ option . id ] : {
80+ updatedIndex : index ,
81+ updatedTop : index * createPollOptionHeight ,
82+ } ,
83+ } ,
84+ } ;
85+ } ) ;
9386 // eslint-disable-next-line react-hooks/exhaustive-deps
9487 } , [ createPollOptionHeight , options . length ] ) ;
9588
96- useEffect ( ( ) => {
97- const seenTexts = new Set < string > ( ) ;
98- const duplicateTexts = new Set < string > ( ) ;
99- for ( const option of options ) {
100- const { text } = option ;
101- if ( seenTexts . has ( text ) ) {
102- duplicateTexts . add ( text ) ;
103- }
104- if ( text . length > 0 ) {
105- seenTexts . add ( text ) ;
106- }
107- }
108-
109- setDuplicates ( Array . from ( duplicateTexts ) ) ;
110- } , [ options ] ) ;
111-
11289 return (
11390 < >
114- < View style = { [ styles . headerContainer , { backgroundColor : white } , headerContainer ] } >
115- < PollModalHeader
116- onPress = { ( ) => {
117- pollComposer . initState ( ) ;
118- closePollCreationDialog ?.( ) ;
119- } }
120- title = { t ( 'Create Poll' ) }
121- />
122- < Pressable
123- disabled = { ! canCreatePoll }
124- onPress = { async ( ) => {
125- const currentPollOptions = Object . assign ( { } , options ) ;
126- const reorderedPollOptions = [ ] ;
127-
128- for ( let i = 0 ; i < options . length ; i ++ ) {
129- const currentOption =
130- currentPollOptions [ currentOptionPositions . value . inverseIndexCache [ i ] ] ;
131- if ( currentOption . text . length > 0 ) {
132- reorderedPollOptions . push ( currentOption ) ;
133- }
134- }
135- await pollComposer . updateFields ( {
136- options : reorderedPollOptions ,
137- } ) ;
138- await createAndSendPoll ( ) ;
139- } }
140- style = { ( { pressed } ) => [ { opacity : pressed ? 0.5 : 1 } , styles . sendButton , sendButton ] }
141- >
142- < SendPoll
143- height = { 24 }
144- pathFill = { canCreatePoll ? '#005DFF' : '#B4BBBA' }
145- viewBox = '0 0 24 24'
146- width = { 24 }
147- />
148- </ Pressable >
149- </ View >
91+ < CreatePollHeader />
15092 < ScrollView
15193 contentContainerStyle = { { paddingBottom : 70 } }
15294 style = { [ styles . scrollView , { backgroundColor : white } , scrollView ] }
15395 >
15496 < NameField />
155- < CreatePollOptions
156- currentOptionPositions = { currentOptionPositions }
157- duplicates = { duplicates }
158- />
97+ < CreatePollOptions currentOptionPositions = { currentOptionPositions } />
15998 < MultipleAnswersField />
16099 < View
161100 style = { [ styles . textInputWrapper , { backgroundColor : bg_user } , anonymousPoll . wrapper ] }
@@ -202,7 +141,7 @@ export const CreatePollContent = () => {
202141export const CreatePoll = ( {
203142 closePollCreationDialog,
204143 CreatePollContent : CreatePollContentOverride ,
205- createPollOptionHeight = 71 ,
144+ createPollOptionHeight = POLL_OPTION_HEIGHT ,
206145 sendMessage,
207146} : Pick <
208147 CreatePollContentContextValue ,
@@ -233,9 +172,7 @@ export const CreatePoll = ({
233172} ;
234173
235174const styles = StyleSheet . create ( {
236- headerContainer : { flexDirection : 'row' , justifyContent : 'space-between' } ,
237175 scrollView : { flex : 1 , padding : 16 } ,
238- sendButton : { paddingHorizontal : 16 , paddingVertical : 18 } ,
239176 text : { fontSize : 16 } ,
240177 textInputWrapper : {
241178 alignItems : 'center' ,
0 commit comments