stream-chat-react 12.4.1 → 12.5.0

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.
Files changed (180) hide show
  1. package/dist/assets/icons/stream-chat-icons.eot +0 -0
  2. package/dist/assets/icons/stream-chat-icons.svg +4 -0
  3. package/dist/assets/icons/stream-chat-icons.ttf +0 -0
  4. package/dist/assets/icons/stream-chat-icons.woff +0 -0
  5. package/dist/assets/icons/stream-chat-icons.woff2 +0 -0
  6. package/dist/components/Attachment/components/ProgressBar.d.ts +2 -2
  7. package/dist/components/Attachment/components/ProgressBar.js +2 -1
  8. package/dist/components/Channel/Channel.d.ts +1 -1
  9. package/dist/components/Channel/Channel.js +36 -15
  10. package/dist/components/Channel/constants.d.ts +1 -0
  11. package/dist/components/Channel/constants.js +1 -0
  12. package/dist/components/Channel/hooks/useChannelContainerClasses.d.ts +2 -0
  13. package/dist/components/Channel/hooks/useChannelContainerClasses.js +10 -5
  14. package/dist/components/ChannelPreview/utils.js +35 -0
  15. package/dist/components/Chat/hooks/useChat.js +2 -0
  16. package/dist/components/Dialog/DialogAnchor.d.ts +1 -2
  17. package/dist/components/Dialog/DialogMenu.d.ts +3 -0
  18. package/dist/components/Dialog/DialogMenu.js +5 -0
  19. package/dist/components/Dialog/DialogPortal.d.ts +1 -1
  20. package/dist/components/Dialog/DialogPortal.js +4 -12
  21. package/dist/components/Dialog/FormDialog.d.ts +23 -0
  22. package/dist/components/Dialog/FormDialog.js +72 -0
  23. package/dist/components/Dialog/PromptDialog.d.ts +8 -0
  24. package/dist/components/Dialog/PromptDialog.js +7 -0
  25. package/dist/components/DragAndDrop/DragAndDropContainer.d.ts +7 -0
  26. package/dist/components/DragAndDrop/DragAndDropContainer.js +93 -0
  27. package/dist/components/Form/FieldError.d.ts +6 -0
  28. package/dist/components/Form/FieldError.js +3 -0
  29. package/dist/components/Form/SwitchField.d.ts +7 -0
  30. package/dist/components/Form/SwitchField.js +21 -0
  31. package/dist/components/InfiniteScrollPaginator/InfiniteScroll.d.ts +10 -0
  32. package/dist/components/InfiniteScrollPaginator/InfiniteScroll.js +10 -0
  33. package/dist/components/InfiniteScrollPaginator/InfiniteScrollPaginator.d.ts +10 -0
  34. package/dist/components/InfiniteScrollPaginator/InfiniteScrollPaginator.js +68 -0
  35. package/dist/components/InfiniteScrollPaginator/hooks/useCursorPaginator.d.ts +18 -0
  36. package/dist/components/InfiniteScrollPaginator/hooks/useCursorPaginator.js +41 -0
  37. package/dist/components/Message/MessageSimple.js +5 -1
  38. package/dist/components/Message/QuotedMessage.js +8 -4
  39. package/dist/components/Message/hooks/useUserRole.js +3 -2
  40. package/dist/components/Message/index.d.ts +1 -0
  41. package/dist/components/MessageInput/AttachmentSelector.d.ts +25 -0
  42. package/dist/components/MessageInput/AttachmentSelector.js +125 -0
  43. package/dist/components/MessageInput/EditMessageForm.js +1 -1
  44. package/dist/components/MessageInput/MessageInput.d.ts +2 -0
  45. package/dist/components/MessageInput/MessageInput.js +9 -4
  46. package/dist/components/MessageInput/MessageInputFlat.js +4 -10
  47. package/dist/components/MessageInput/QuotedMessagePreview.js +7 -3
  48. package/dist/components/MessageInput/hooks/useCreateMessageInputContext.js +3 -1
  49. package/dist/components/MessageInput/hooks/useSubmitHandler.js +4 -1
  50. package/dist/components/MessageInput/index.d.ts +1 -0
  51. package/dist/components/MessageInput/index.js +1 -0
  52. package/dist/components/Modal/ModalHeader.d.ts +8 -0
  53. package/dist/components/Modal/ModalHeader.js +6 -0
  54. package/dist/components/Poll/Poll.d.ts +7 -0
  55. package/dist/components/Poll/Poll.js +8 -0
  56. package/dist/components/Poll/PollActions/AddCommentForm.d.ts +7 -0
  57. package/dist/components/Poll/PollActions/AddCommentForm.js +24 -0
  58. package/dist/components/Poll/PollActions/EndPollDialog.d.ts +6 -0
  59. package/dist/components/Poll/PollActions/EndPollDialog.js +19 -0
  60. package/dist/components/Poll/PollActions/PollAction.d.ts +9 -0
  61. package/dist/components/Poll/PollActions/PollAction.js +5 -0
  62. package/dist/components/Poll/PollActions/PollActions.d.ts +17 -0
  63. package/dist/components/Poll/PollActions/PollActions.js +46 -0
  64. package/dist/components/Poll/PollActions/PollAnswerList.d.ts +7 -0
  65. package/dist/components/Poll/PollActions/PollAnswerList.js +28 -0
  66. package/dist/components/Poll/PollActions/PollOptionsFullList.d.ts +6 -0
  67. package/dist/components/Poll/PollActions/PollOptionsFullList.js +16 -0
  68. package/dist/components/Poll/PollActions/PollResults/PollOptionVotesList.d.ts +7 -0
  69. package/dist/components/Poll/PollActions/PollResults/PollOptionVotesList.js +18 -0
  70. package/dist/components/Poll/PollActions/PollResults/PollOptionWithLatestVotes.d.ts +9 -0
  71. package/dist/components/Poll/PollActions/PollResults/PollOptionWithLatestVotes.js +19 -0
  72. package/dist/components/Poll/PollActions/PollResults/PollOptionWithVotesHeader.d.ts +11 -0
  73. package/dist/components/Poll/PollActions/PollResults/PollOptionWithVotesHeader.js +18 -0
  74. package/dist/components/Poll/PollActions/PollResults/PollResults.d.ts +6 -0
  75. package/dist/components/Poll/PollActions/PollResults/PollResults.js +33 -0
  76. package/dist/components/Poll/PollActions/PollResults/index.d.ts +1 -0
  77. package/dist/components/Poll/PollActions/PollResults/index.js +1 -0
  78. package/dist/components/Poll/PollActions/SuggestPollOptionForm.d.ts +7 -0
  79. package/dist/components/Poll/PollActions/SuggestPollOptionForm.js +37 -0
  80. package/dist/components/Poll/PollActions/index.d.ts +7 -0
  81. package/dist/components/Poll/PollActions/index.js +7 -0
  82. package/dist/components/Poll/PollContent.d.ts +3 -0
  83. package/dist/components/Poll/PollContent.js +18 -0
  84. package/dist/components/Poll/PollCreationDialog/OptionFieldSet.d.ts +9 -0
  85. package/dist/components/Poll/PollCreationDialog/OptionFieldSet.js +70 -0
  86. package/dist/components/Poll/PollCreationDialog/PollCreationDialog.d.ts +5 -0
  87. package/dist/components/Poll/PollCreationDialog/PollCreationDialog.js +87 -0
  88. package/dist/components/Poll/PollCreationDialog/PollCreationDialogControls.d.ts +8 -0
  89. package/dist/components/Poll/PollCreationDialog/PollCreationDialogControls.js +44 -0
  90. package/dist/components/Poll/PollCreationDialog/index.d.ts +1 -0
  91. package/dist/components/Poll/PollCreationDialog/index.js +1 -0
  92. package/dist/components/Poll/PollCreationDialog/types.d.ts +21 -0
  93. package/dist/components/Poll/PollCreationDialog/types.js +1 -0
  94. package/dist/components/Poll/PollHeader.d.ts +3 -0
  95. package/dist/components/Poll/PollHeader.js +31 -0
  96. package/dist/components/Poll/PollOptionList.d.ts +6 -0
  97. package/dist/components/Poll/PollOptionList.js +14 -0
  98. package/dist/components/Poll/PollOptionSelector.d.ts +19 -0
  99. package/dist/components/Poll/PollOptionSelector.js +53 -0
  100. package/dist/components/Poll/PollVote.d.ts +12 -0
  101. package/dist/components/Poll/PollVote.js +31 -0
  102. package/dist/components/Poll/QuotedPoll.d.ts +3 -0
  103. package/dist/components/Poll/QuotedPoll.js +17 -0
  104. package/dist/components/Poll/constants.d.ts +3 -0
  105. package/dist/components/Poll/constants.js +3 -0
  106. package/dist/components/Poll/hooks/index.d.ts +2 -0
  107. package/dist/components/Poll/hooks/index.js +2 -0
  108. package/dist/components/Poll/hooks/useManagePollVotesRealtime.d.ts +4 -0
  109. package/dist/components/Poll/hooks/useManagePollVotesRealtime.js +36 -0
  110. package/dist/components/Poll/hooks/usePollAnswerPagination.d.ts +13 -0
  111. package/dist/components/Poll/hooks/usePollAnswerPagination.js +27 -0
  112. package/dist/components/Poll/hooks/usePollOptionVotesPagination.d.ts +13 -0
  113. package/dist/components/Poll/hooks/usePollOptionVotesPagination.js +27 -0
  114. package/dist/components/Poll/index.d.ts +10 -0
  115. package/dist/components/Poll/index.js +10 -0
  116. package/dist/components/Portal/Portal.d.ts +6 -0
  117. package/dist/components/Portal/Portal.js +14 -0
  118. package/dist/components/ReactFileUtilities/UploadButton.d.ts +11 -1
  119. package/dist/components/ReactFileUtilities/UploadButton.js +22 -4
  120. package/dist/components/Thread/Thread.js +1 -1
  121. package/dist/components/index.d.ts +2 -0
  122. package/dist/components/index.js +1 -0
  123. package/dist/context/AttachmentSelectorContext.d.ts +8 -0
  124. package/dist/context/AttachmentSelectorContext.js +6 -0
  125. package/dist/context/ComponentContext.d.ts +21 -5
  126. package/dist/context/PollContext.d.ts +11 -0
  127. package/dist/context/PollContext.js +7 -0
  128. package/dist/context/index.d.ts +1 -0
  129. package/dist/context/index.js +1 -0
  130. package/dist/css/v2/index.css +2 -2
  131. package/dist/css/v2/index.layout.css +2 -2
  132. package/dist/experimental/index.browser.cjs +129 -117
  133. package/dist/experimental/index.browser.cjs.map +4 -4
  134. package/dist/experimental/index.node.cjs +129 -117
  135. package/dist/experimental/index.node.cjs.map +4 -4
  136. package/dist/i18n/Streami18n.d.ts +45 -0
  137. package/dist/i18n/de.json +70 -25
  138. package/dist/i18n/en.json +46 -1
  139. package/dist/i18n/es.json +74 -25
  140. package/dist/i18n/fr.json +83 -34
  141. package/dist/i18n/hi.json +54 -9
  142. package/dist/i18n/it.json +75 -26
  143. package/dist/i18n/ja.json +46 -5
  144. package/dist/i18n/ko.json +46 -5
  145. package/dist/i18n/nl.json +59 -14
  146. package/dist/i18n/pt.json +66 -17
  147. package/dist/i18n/ru.json +66 -13
  148. package/dist/i18n/tr.json +77 -32
  149. package/dist/index.browser.cjs +4226 -1857
  150. package/dist/index.browser.cjs.map +4 -4
  151. package/dist/index.node.cjs +4166 -1770
  152. package/dist/index.node.cjs.map +4 -4
  153. package/dist/scss/v2/AttachmentPreviewList/AttachmentPreviewList-layout.scss +2 -2
  154. package/dist/scss/v2/AudioRecorder/AudioRecorder-layout.scss +64 -14
  155. package/dist/scss/v2/AudioRecorder/AudioRecorder-theme.scss +11 -1
  156. package/dist/scss/v2/Avatar/Avatar-layout.scss +4 -0
  157. package/dist/scss/v2/ChannelList/ChannelList-layout.scss +15 -0
  158. package/dist/scss/v2/Dialog/Dialog-layout.scss +54 -0
  159. package/dist/scss/v2/Dialog/Dialog-theme.scss +103 -0
  160. package/dist/scss/v2/DragAndDropContainer/DragAmdDropContainer-layout.scss +5 -0
  161. package/dist/scss/v2/DragAndDropContainer/DragAndDropContainer-theme.scss +47 -0
  162. package/dist/scss/v2/Form/Form-layout.scss +9 -0
  163. package/dist/scss/v2/Form/Form-theme.scss +17 -0
  164. package/dist/scss/v2/Icon/Icon-layout.scss +6 -1
  165. package/dist/scss/v2/InfiniteScrollPaginator/InfiniteScrollPaginator-layout.scss +4 -0
  166. package/dist/scss/v2/MessageActionsBox/MessageActionsBox-layout.scss +0 -9
  167. package/dist/scss/v2/MessageInput/MessageInput-layout.scss +29 -4
  168. package/dist/scss/v2/MessageInput/MessageInput-theme.scss +61 -0
  169. package/dist/scss/v2/Modal/Modal-layout.scss +31 -0
  170. package/dist/scss/v2/Modal/Modal-theme.scss +6 -0
  171. package/dist/scss/v2/Notification/MessageNotification-layout.scss +1 -1
  172. package/dist/scss/v2/Poll/Poll-layout.scss +488 -0
  173. package/dist/scss/v2/Poll/Poll-theme.scss +206 -0
  174. package/dist/scss/v2/_base.scss +4 -0
  175. package/dist/scss/v2/_global-theme-variables.scss +1 -1
  176. package/dist/scss/v2/_icons.scss +7 -0
  177. package/dist/scss/v2/index.layout.scss +4 -0
  178. package/dist/scss/v2/index.scss +4 -0
  179. package/dist/types/types.d.ts +6 -0
  180. package/package.json +4 -4
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { PollContent as DefaultPollContent } from './PollContent';
3
+ import { QuotedPoll as DefaultQuotedPoll } from './QuotedPoll';
4
+ import { PollProvider, useComponentContext } from '../../context';
5
+ export const Poll = ({ isQuoted, poll, }) => {
6
+ const { PollContent = DefaultPollContent, QuotedPoll = DefaultQuotedPoll, } = useComponentContext();
7
+ return poll ? (React.createElement(PollProvider, { poll: poll }, isQuoted ? React.createElement(QuotedPoll, null) : React.createElement(PollContent, null))) : null;
8
+ };
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import type { DefaultStreamChatGenerics } from '../../../types';
3
+ export type AddCommentFormProps = {
4
+ close: () => void;
5
+ messageId: string;
6
+ };
7
+ export declare const AddCommentForm: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ close, messageId, }: AddCommentFormProps) => React.JSX.Element;
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { FormDialog } from '../../Dialog/FormDialog';
3
+ import { useStateStore } from '../../../store';
4
+ import { usePollContext, useTranslationContext } from '../../../context';
5
+ const pollStateSelector = (nextValue) => ({ ownAnswer: nextValue.ownAnswer });
6
+ export const AddCommentForm = ({ close, messageId, }) => {
7
+ const { t } = useTranslationContext('AddCommentForm');
8
+ const { poll } = usePollContext();
9
+ const { ownAnswer } = useStateStore(poll.state, pollStateSelector);
10
+ return (React.createElement(FormDialog, { className: 'str-chat__prompt-dialog str-chat__modal__poll-add-comment', close: close, fields: {
11
+ comment: {
12
+ element: 'input',
13
+ props: {
14
+ id: 'comment',
15
+ name: 'comment',
16
+ required: true,
17
+ type: 'text',
18
+ value: ownAnswer?.answer_text ?? '',
19
+ },
20
+ },
21
+ }, onSubmit: async (value) => {
22
+ await poll.addAnswer(value.comment, messageId);
23
+ }, shouldDisableSubmitButton: (value) => !value.comment || value.comment === ownAnswer?.answer_text, title: ownAnswer ? t('Update your comment') : t('Add a comment') }));
24
+ };
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import type { DefaultStreamChatGenerics } from '../../../types';
3
+ export type EndPollDialogProps = {
4
+ close: () => void;
5
+ };
6
+ export declare const EndPollDialog: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ close, }: EndPollDialogProps) => React.JSX.Element;
@@ -0,0 +1,19 @@
1
+ import { PromptDialog } from '../../Dialog/PromptDialog';
2
+ import React from 'react';
3
+ import { usePollContext, useTranslationContext } from '../../../context';
4
+ export const EndPollDialog = ({ close, }) => {
5
+ const { t } = useTranslationContext('SuggestPollOptionForm');
6
+ const { poll } = usePollContext();
7
+ return (React.createElement(PromptDialog, { actions: [
8
+ {
9
+ children: t('Cancel'),
10
+ className: 'str-chat__dialog__controls-button--cancel',
11
+ onClick: close,
12
+ },
13
+ {
14
+ children: t('End'),
15
+ className: '.str-chat__dialog__controls-button--submit str-chat__dialog__controls-button--end-poll',
16
+ onClick: poll.close,
17
+ },
18
+ ], className: 'str-chat__modal__end-vote', prompt: t('Nobody will be able to vote in this poll anymore.'), title: t('End vote') }));
19
+ };
@@ -0,0 +1,9 @@
1
+ import React, { PropsWithChildren } from 'react';
2
+ export type PollActionProps = {
3
+ buttonText: string;
4
+ closeModal: () => void;
5
+ modalIsOpen: boolean;
6
+ openModal: () => void;
7
+ modalClassName?: string;
8
+ };
9
+ export declare const PollAction: ({ buttonText, children, closeModal, modalClassName, modalIsOpen, openModal, }: PropsWithChildren<PollActionProps>) => React.JSX.Element;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { Modal } from '../../Modal';
3
+ export const PollAction = ({ buttonText, children, closeModal, modalClassName, modalIsOpen, openModal, }) => (React.createElement(React.Fragment, null,
4
+ React.createElement("button", { className: 'str-chat__poll-action', onClick: openModal }, buttonText),
5
+ React.createElement(Modal, { className: modalClassName, onClose: closeModal, open: modalIsOpen }, children)));
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { AddCommentFormProps } from './AddCommentForm';
3
+ import { SuggestPollOptionFormProps } from './SuggestPollOptionForm';
4
+ import { EndPollDialogProps } from './EndPollDialog';
5
+ import { PollAnswerListProps } from './PollAnswerList';
6
+ import { FullPollOptionsListingProps } from './PollOptionsFullList';
7
+ import { PollResultsProps } from './PollResults';
8
+ import type { DefaultStreamChatGenerics } from '../../../types';
9
+ export type PollActionsProps = {
10
+ AddCommentForm?: React.ComponentType<AddCommentFormProps>;
11
+ EndPollDialog?: React.ComponentType<EndPollDialogProps>;
12
+ PollAnswerList?: React.ComponentType<PollAnswerListProps>;
13
+ PollOptionsFullList?: React.ComponentType<FullPollOptionsListingProps>;
14
+ PollResults?: React.ComponentType<PollResultsProps>;
15
+ SuggestPollOptionForm?: React.ComponentType<SuggestPollOptionFormProps>;
16
+ };
17
+ export declare const PollActions: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ AddCommentForm, EndPollDialog, PollAnswerList, PollOptionsFullList, PollResults, SuggestPollOptionForm, }: PollActionsProps) => React.JSX.Element;
@@ -0,0 +1,46 @@
1
+ import React, { useCallback, useState } from 'react';
2
+ import { PollAction } from './PollAction';
3
+ import { AddCommentForm as DefaultAddCommentForm } from './AddCommentForm';
4
+ import { SuggestPollOptionForm as DefaultSuggestPollOptionForm, } from './SuggestPollOptionForm';
5
+ import { EndPollDialog as DefaultEndPollDialog } from './EndPollDialog';
6
+ import { PollAnswerList as DefaultPollAnswerList } from './PollAnswerList';
7
+ import { PollOptionsFullList as DefaultPollOptionsFullList, } from './PollOptionsFullList';
8
+ import { PollResults as DefaultPollResults } from './PollResults';
9
+ import { MAX_OPTIONS_DISPLAYED, MAX_POLL_OPTIONS } from '../constants';
10
+ import { useChannelStateContext, useChatContext, useMessageContext, usePollContext, useTranslationContext, } from '../../../context';
11
+ import { useStateStore } from '../../../store';
12
+ const pollStateSelector = (nextValue) => ({
13
+ allow_answers: nextValue.allow_answers,
14
+ allow_user_suggested_options: nextValue.allow_user_suggested_options,
15
+ answers_count: nextValue.answers_count,
16
+ created_by_id: nextValue.created_by_id,
17
+ is_closed: nextValue.is_closed,
18
+ options: nextValue.options,
19
+ ownAnswer: nextValue.ownAnswer,
20
+ });
21
+ export const PollActions = ({ AddCommentForm = DefaultAddCommentForm, EndPollDialog = DefaultEndPollDialog, PollAnswerList = DefaultPollAnswerList, PollOptionsFullList = DefaultPollOptionsFullList, PollResults = DefaultPollResults, SuggestPollOptionForm = DefaultSuggestPollOptionForm, }) => {
22
+ const { client } = useChatContext();
23
+ const { t } = useTranslationContext('PollActions');
24
+ const { channelCapabilities = {} } = useChannelStateContext('PollActions');
25
+ const { message } = useMessageContext('PollActions');
26
+ const { poll } = usePollContext();
27
+ const { allow_answers, allow_user_suggested_options, answers_count, created_by_id, is_closed, options, ownAnswer, } = useStateStore(poll.state, pollStateSelector);
28
+ const [modalOpen, setModalOpen] = useState();
29
+ const closeModal = useCallback(() => setModalOpen(undefined), []);
30
+ const onUpdateAnswerClick = useCallback(() => setModalOpen('add-comment'), []);
31
+ return (React.createElement("div", { className: 'str-chat__poll-actions' },
32
+ options.length > MAX_OPTIONS_DISPLAYED && (React.createElement(PollAction, { buttonText: t('See all options ({{count}})', {
33
+ count: options.length,
34
+ }), closeModal: closeModal, modalIsOpen: modalOpen === 'view-all-options', openModal: () => setModalOpen('view-all-options') },
35
+ React.createElement(PollOptionsFullList, { close: closeModal }))),
36
+ !is_closed && allow_user_suggested_options && options.length < MAX_POLL_OPTIONS && (React.createElement(PollAction, { buttonText: t('Suggest an option'), closeModal: closeModal, modalClassName: 'str-chat__suggest-poll-option-modal', modalIsOpen: modalOpen === 'suggest-option', openModal: () => setModalOpen('suggest-option') },
37
+ React.createElement(SuggestPollOptionForm, { close: closeModal, messageId: message.id }))),
38
+ !is_closed && allow_answers && (React.createElement(PollAction, { buttonText: ownAnswer ? t('Update your comment') : t('Add a comment'), closeModal: closeModal, modalClassName: 'str-chat__add-poll-answer-modal', modalIsOpen: modalOpen === 'add-comment', openModal: () => setModalOpen('add-comment') },
39
+ React.createElement(AddCommentForm, { close: closeModal, messageId: message.id }))),
40
+ answers_count > 0 && channelCapabilities['query-poll-votes'] && (React.createElement(PollAction, { buttonText: t('View {{count}} comments', { count: answers_count }), closeModal: closeModal, modalClassName: 'str-chat__poll-answer-list-modal', modalIsOpen: modalOpen === 'view-comments', openModal: () => setModalOpen('view-comments') },
41
+ React.createElement(PollAnswerList, { close: closeModal, onUpdateOwnAnswerClick: onUpdateAnswerClick }))),
42
+ React.createElement(PollAction, { buttonText: t('View results'), closeModal: closeModal, modalClassName: 'str-chat__poll-results-modal', modalIsOpen: modalOpen === 'view-results', openModal: () => setModalOpen('view-results') },
43
+ React.createElement(PollResults, { close: closeModal })),
44
+ !is_closed && created_by_id === client.user?.id && (React.createElement(PollAction, { buttonText: t('End vote'), closeModal: closeModal, modalClassName: 'str-chat__end-poll-modal', modalIsOpen: modalOpen === 'end-vote', openModal: () => setModalOpen('end-vote') },
45
+ React.createElement(EndPollDialog, { close: closeModal })))));
46
+ };
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import type { DefaultStreamChatGenerics } from '../../../types';
3
+ export type PollAnswerListProps = {
4
+ onUpdateOwnAnswerClick: () => void;
5
+ close?: () => void;
6
+ };
7
+ export declare const PollAnswerList: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ close, onUpdateOwnAnswerClick, }: PollAnswerListProps) => React.JSX.Element;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { ModalHeader } from '../../Modal/ModalHeader';
3
+ import { PollVote } from '../PollVote';
4
+ import { usePollAnswerPagination } from '../hooks';
5
+ import { InfiniteScrollPaginator } from '../../InfiniteScrollPaginator/InfiniteScrollPaginator';
6
+ import { LoadingIndicator } from '../../Loading';
7
+ import { useStateStore } from '../../../store';
8
+ import { usePollContext, useTranslationContext } from '../../../context';
9
+ const pollStateSelector = (nextValue) => ({
10
+ is_closed: nextValue.is_closed,
11
+ ownAnswer: nextValue.ownAnswer,
12
+ });
13
+ export const PollAnswerList = ({ close, onUpdateOwnAnswerClick, }) => {
14
+ const { t } = useTranslationContext();
15
+ const { poll } = usePollContext();
16
+ const { is_closed, ownAnswer } = useStateStore(poll.state, pollStateSelector);
17
+ const { answers, error, hasNextPage, loading, loadMore, } = usePollAnswerPagination();
18
+ return (React.createElement("div", { className: 'str-chat__modal__poll-answer-list' },
19
+ React.createElement(ModalHeader, { close: close, title: t('Poll comments') }),
20
+ React.createElement("div", { className: 'str-chat__modal__poll-answer-list__body' },
21
+ React.createElement(InfiniteScrollPaginator, { loadNextOnScrollToBottom: loadMore, threshold: 40 },
22
+ React.createElement("div", { className: 'str-chat__poll-answer-list' }, answers.map((answer) => (React.createElement("div", { className: 'str-chat__poll-answer', key: `comment-${answer.id}` },
23
+ answer.answer_text && (React.createElement("p", { className: 'str-chat__poll-answer__text' }, answer.answer_text)),
24
+ React.createElement(PollVote, { key: `poll-vote-${answer.id}`, vote: answer }))))),
25
+ hasNextPage && (React.createElement("div", { className: 'str-chat__loading-indicator-placeholder' }, loading && React.createElement(LoadingIndicator, null)))),
26
+ error?.message && React.createElement("div", null, error?.message)),
27
+ answers.length > 0 && !is_closed && (React.createElement("button", { className: 'str-chat__poll-action', onClick: onUpdateOwnAnswerClick }, ownAnswer ? t('Update your comment') : t('Add a comment')))));
28
+ };
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import type { DefaultStreamChatGenerics } from '../../../types';
3
+ export type FullPollOptionsListingProps = {
4
+ close?: () => void;
5
+ };
6
+ export declare const PollOptionsFullList: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ close, }: FullPollOptionsListingProps) => React.JSX.Element;
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import { ModalHeader } from '../../Modal/ModalHeader';
3
+ import { PollOptionList } from '../PollOptionList';
4
+ import { useStateStore } from '../../../store';
5
+ import { usePollContext, useTranslationContext } from '../../../context';
6
+ const pollStateSelector = (nextValue) => ({ name: nextValue.name });
7
+ export const PollOptionsFullList = ({ close, }) => {
8
+ const { t } = useTranslationContext();
9
+ const { poll } = usePollContext();
10
+ const { name } = useStateStore(poll.state, pollStateSelector);
11
+ return (React.createElement("div", { className: 'str-chat__modal__poll-option-list' },
12
+ React.createElement(ModalHeader, { close: close, title: t('Poll options') }),
13
+ React.createElement("div", { className: 'str-chat__modal__poll-option-list__body' },
14
+ React.createElement("div", { className: 'str-chat__modal__poll-option-list__title' }, name),
15
+ React.createElement(PollOptionList, null))));
16
+ };
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import type { PollOption } from 'stream-chat';
3
+ import type { DefaultStreamChatGenerics } from '../../../../types';
4
+ export type PollOptionVotesListingProps<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = {
5
+ option: PollOption<StreamChatGenerics>;
6
+ };
7
+ export declare const PollOptionVotesList: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ option, }: PollOptionVotesListingProps<StreamChatGenerics>) => React.JSX.Element;
@@ -0,0 +1,18 @@
1
+ import React, { useMemo } from 'react';
2
+ import { PollVoteListing } from '../../PollVote';
3
+ import { usePollOptionVotesPagination } from '../../hooks';
4
+ import { LoadingIndicator } from '../../../Loading';
5
+ import { InfiniteScrollPaginator } from '../../../InfiniteScrollPaginator/InfiniteScrollPaginator';
6
+ import { PollOptionWithVotesHeader } from './PollOptionWithVotesHeader';
7
+ export const PollOptionVotesList = ({ option, }) => {
8
+ const paginationParams = useMemo(() => ({ filter: { option_id: option.id } }), [option.id]);
9
+ const { error, hasNextPage, loading, loadMore, votes, } = usePollOptionVotesPagination({
10
+ paginationParams,
11
+ });
12
+ return (React.createElement("div", { className: 'str-chat__poll-option str-chat__poll-option--full-vote-list' },
13
+ React.createElement(PollOptionWithVotesHeader, { option: option }),
14
+ React.createElement(InfiniteScrollPaginator, { loadNextOnScrollToBottom: loadMore, threshold: 40 },
15
+ React.createElement(PollVoteListing, { votes: votes }),
16
+ hasNextPage && (React.createElement("div", { className: 'str-chat__loading-indicator-placeholder' }, loading && React.createElement(LoadingIndicator, null)))),
17
+ error && error.message));
18
+ };
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import type { PollOption } from 'stream-chat';
3
+ import type { DefaultStreamChatGenerics } from '../../../../types';
4
+ export type PollOptionWithVotesProps<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = {
5
+ option: PollOption<StreamChatGenerics>;
6
+ countVotesPreview?: number;
7
+ showAllVotes?: () => void;
8
+ };
9
+ export declare const PollOptionWithLatestVotes: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ countVotesPreview, option, showAllVotes, }: PollOptionWithVotesProps<StreamChatGenerics>) => React.JSX.Element;
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { PollOptionWithVotesHeader } from './PollOptionWithVotesHeader';
3
+ import { PollVoteListing } from '../../PollVote';
4
+ import { useStateStore } from '../../../../store';
5
+ import { useChannelStateContext, usePollContext, useTranslationContext } from '../../../../context';
6
+ const pollStateSelector = (nextValue) => ({ latest_votes_by_option: nextValue.latest_votes_by_option });
7
+ export const PollOptionWithLatestVotes = ({ countVotesPreview = 5, option, showAllVotes, }) => {
8
+ const { t } = useTranslationContext();
9
+ const { channelCapabilities = {} } = useChannelStateContext('PollOptionWithLatestVotes');
10
+ const { poll } = usePollContext();
11
+ const { latest_votes_by_option } = useStateStore(poll.state, pollStateSelector);
12
+ const votes = latest_votes_by_option && latest_votes_by_option[option.id];
13
+ return (React.createElement("div", { className: 'str-chat__poll-option' },
14
+ React.createElement(PollOptionWithVotesHeader, { option: option }),
15
+ votes && React.createElement(PollVoteListing, { votes: votes.slice(0, countVotesPreview) }),
16
+ channelCapabilities['query-poll-votes'] &&
17
+ showAllVotes &&
18
+ votes?.length > countVotesPreview && (React.createElement("button", { className: 'str-chat__poll-option__show-all-votes-button', onClick: showAllVotes }, t('Show all')))));
19
+ };
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import type { PollOption } from 'stream-chat';
3
+ import type { DefaultStreamChatGenerics } from '../../../../types';
4
+ export type PollResultOptionVoteCounterProps = {
5
+ optionId: string;
6
+ };
7
+ export declare const PollResultOptionVoteCounter: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ optionId, }: PollResultOptionVoteCounterProps) => React.JSX.Element;
8
+ export type PollOptionWithVotesHeaderProps<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = {
9
+ option: PollOption<StreamChatGenerics>;
10
+ };
11
+ export declare const PollOptionWithVotesHeader: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ option, }: PollOptionWithVotesHeaderProps<StreamChatGenerics>) => React.JSX.Element;
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import { useStateStore } from '../../../../store';
3
+ import { usePollContext, useTranslationContext } from '../../../../context';
4
+ const pollStateSelector = (nextValue) => ({
5
+ maxVotedOptionIds: nextValue.maxVotedOptionIds,
6
+ vote_counts_by_option: nextValue.vote_counts_by_option,
7
+ });
8
+ export const PollResultOptionVoteCounter = ({ optionId, }) => {
9
+ const { t } = useTranslationContext();
10
+ const { poll } = usePollContext();
11
+ const { maxVotedOptionIds, vote_counts_by_option } = useStateStore(poll.state, pollStateSelector);
12
+ return (React.createElement("div", { className: 'str-chat__poll-result-option-vote-counter' },
13
+ maxVotedOptionIds.length === 1 && maxVotedOptionIds[0] === optionId && (React.createElement("div", { className: 'str-chat__poll-result-winning-option-icon' })),
14
+ React.createElement("span", { className: 'str-chat__poll-result-option-vote-count' }, t('{{count}} votes', { count: vote_counts_by_option[optionId] ?? 0 }))));
15
+ };
16
+ export const PollOptionWithVotesHeader = ({ option, }) => (React.createElement("div", { className: 'str-chat__poll-option__header' },
17
+ React.createElement("div", { className: 'str-chat__poll-option__option-text' }, option.text),
18
+ React.createElement(PollResultOptionVoteCounter, { optionId: option.id })));
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ import type { DefaultStreamChatGenerics } from '../../../../types';
3
+ export type PollResultsProps = {
4
+ close?: () => void;
5
+ };
6
+ export declare const PollResults: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ close, }: PollResultsProps) => React.JSX.Element;
@@ -0,0 +1,33 @@
1
+ import clsx from 'clsx';
2
+ import React, { useCallback, useState } from 'react';
3
+ import { PollOptionVotesList } from './PollOptionVotesList';
4
+ import { PollOptionWithLatestVotes } from './PollOptionWithLatestVotes';
5
+ import { ModalHeader } from '../../../Modal/ModalHeader';
6
+ import { useStateStore } from '../../../../store';
7
+ import { usePollContext, useTranslationContext } from '../../../../context';
8
+ const pollStateSelector = (nextValue) => ({
9
+ name: nextValue.name,
10
+ options: nextValue.options,
11
+ vote_counts_by_option: nextValue.vote_counts_by_option,
12
+ });
13
+ export const PollResults = ({ close, }) => {
14
+ const { t } = useTranslationContext();
15
+ const { poll } = usePollContext();
16
+ const { name, options, vote_counts_by_option } = useStateStore(poll.state, pollStateSelector);
17
+ const [optionToView, setOptionToView] = useState();
18
+ const goBack = useCallback(() => setOptionToView(undefined), []);
19
+ return (React.createElement("div", { className: clsx('str-chat__modal__poll-results', {
20
+ 'str-chat__modal__poll-results--option-detail': optionToView,
21
+ }) }, optionToView ? (React.createElement(React.Fragment, null,
22
+ React.createElement(ModalHeader, { close: close, goBack: goBack, title: optionToView.text }),
23
+ React.createElement("div", { className: 'str-chat__modal__poll-results__body' },
24
+ React.createElement(PollOptionVotesList, { key: `poll-option-detail-${optionToView.id}`, option: optionToView })))) : (React.createElement(React.Fragment, null,
25
+ React.createElement(ModalHeader, { close: close, title: t('Poll results') }),
26
+ React.createElement("div", { className: 'str-chat__modal__poll-results__body' },
27
+ React.createElement("div", { className: 'str-chat__modal__poll-results__title' }, name),
28
+ React.createElement("div", { className: 'str-chat__modal__poll-results__option-list' }, options
29
+ .sort((next, current) => (vote_counts_by_option[current.id] ?? 0) >= (vote_counts_by_option[next.id] ?? 0)
30
+ ? 1
31
+ : -1)
32
+ .map((option) => (React.createElement(PollOptionWithLatestVotes, { key: `poll-option-${option.id}`, option: option, showAllVotes: () => setOptionToView(option) })))))))));
33
+ };
@@ -0,0 +1 @@
1
+ export * from './PollResults';
@@ -0,0 +1 @@
1
+ export * from './PollResults';
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import type { DefaultStreamChatGenerics } from '../../../types';
3
+ export type SuggestPollOptionFormProps = {
4
+ close: () => void;
5
+ messageId: string;
6
+ };
7
+ export declare const SuggestPollOptionForm: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ close, messageId, }: SuggestPollOptionFormProps) => React.JSX.Element;
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import { FormDialog } from '../../Dialog/FormDialog';
3
+ import { useChatContext, usePollContext, useTranslationContext } from '../../../context';
4
+ import { useStateStore } from '../../../store';
5
+ const pollStateSelector = (nextValue) => ({ options: nextValue.options });
6
+ export const SuggestPollOptionForm = ({ close, messageId, }) => {
7
+ const { client } = useChatContext('SuggestPollOptionForm');
8
+ const { t } = useTranslationContext('SuggestPollOptionForm');
9
+ const { poll } = usePollContext();
10
+ const { options } = useStateStore(poll.state, pollStateSelector);
11
+ return (React.createElement(FormDialog, { className: 'str-chat__prompt-dialog str-chat__modal__suggest-poll-option', close: close, fields: {
12
+ optionText: {
13
+ element: 'input',
14
+ props: {
15
+ id: 'optionText',
16
+ name: 'optionText',
17
+ required: true,
18
+ type: 'text',
19
+ value: '',
20
+ },
21
+ validator: (value) => {
22
+ if (!value)
23
+ return;
24
+ const existingOption = options.find((option) => option.text === value.trim());
25
+ if (existingOption) {
26
+ return new Error(t('Option already exists'));
27
+ }
28
+ return;
29
+ },
30
+ },
31
+ }, onSubmit: async (value) => {
32
+ const { poll_option } = await client.createPollOption(poll.id, {
33
+ text: value.optionText,
34
+ });
35
+ poll.castVote(poll_option.id, messageId);
36
+ }, shouldDisableSubmitButton: (value) => !value.optionText, title: t('Suggest an option') }));
37
+ };
@@ -0,0 +1,7 @@
1
+ export * from './AddCommentForm';
2
+ export * from './EndPollDialog';
3
+ export * from './PollActions';
4
+ export * from './PollAnswerList';
5
+ export * from './PollOptionsFullList';
6
+ export * from './PollResults';
7
+ export * from './SuggestPollOptionForm';
@@ -0,0 +1,7 @@
1
+ export * from './AddCommentForm';
2
+ export * from './EndPollDialog';
3
+ export * from './PollActions';
4
+ export * from './PollAnswerList';
5
+ export * from './PollOptionsFullList';
6
+ export * from './PollResults';
7
+ export * from './SuggestPollOptionForm';
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import type { DefaultStreamChatGenerics } from '../../types';
3
+ export declare const PollContent: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>() => React.JSX.Element;
@@ -0,0 +1,18 @@
1
+ import clsx from 'clsx';
2
+ import React from 'react';
3
+ import { PollHeader as DefaultPollHeader } from './PollHeader';
4
+ import { PollActions as DefaultPollActions } from './PollActions';
5
+ import { PollOptionList } from './PollOptionList';
6
+ import { MAX_OPTIONS_DISPLAYED } from './constants';
7
+ import { useComponentContext, usePollContext } from '../../context';
8
+ import { useStateStore } from '../../store';
9
+ const pollStateSelectorPollContent = (nextValue) => ({ is_closed: nextValue.is_closed });
10
+ export const PollContent = () => {
11
+ const { PollHeader = DefaultPollHeader, PollActions = DefaultPollActions, } = useComponentContext();
12
+ const { poll } = usePollContext();
13
+ const { is_closed } = useStateStore(poll.state, pollStateSelectorPollContent);
14
+ return (React.createElement("div", { className: clsx('str-chat__poll', { 'str-chat__poll--closed': is_closed }) },
15
+ React.createElement(PollHeader, null),
16
+ React.createElement(PollOptionList, { optionsDisplayCount: MAX_OPTIONS_DISPLAYED }),
17
+ React.createElement(PollActions, null)));
18
+ };
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import type { OptionErrors, PollFormState } from './types';
3
+ export type OptionFieldSetProps = {
4
+ errors: OptionErrors;
5
+ options: PollFormState['options'];
6
+ setErrors: (fn: (prev: OptionErrors) => OptionErrors) => void;
7
+ setState: (fn: (prev: PollFormState) => PollFormState) => void;
8
+ };
9
+ export declare const OptionFieldSet: ({ errors, options, setErrors, setState }: OptionFieldSetProps) => React.JSX.Element;
@@ -0,0 +1,70 @@
1
+ import clsx from 'clsx';
2
+ import { MAX_POLL_OPTIONS } from '../constants';
3
+ import { nanoid } from 'nanoid';
4
+ import React, { useCallback } from 'react';
5
+ import { FieldError } from '../../Form/FieldError';
6
+ import { DragAndDropContainer } from '../../DragAndDrop/DragAndDropContainer';
7
+ import { useTranslationContext } from '../../../context';
8
+ const VALIDATION_ERRORS = { 'Option already exists': true };
9
+ export const OptionFieldSet = ({ errors, options, setErrors, setState }) => {
10
+ const { t } = useTranslationContext('OptionFieldSet');
11
+ const findOptionDuplicate = (sourceOption) => {
12
+ const isDuplicateFilter = (option) => !!sourceOption.text.trim() && // do not include empty options into consideration
13
+ option.id !== sourceOption.id &&
14
+ option.text.trim() === sourceOption.text.trim();
15
+ return options.find(isDuplicateFilter);
16
+ };
17
+ const onSetNewOrder = useCallback((newOrder) => {
18
+ setState((prev) => ({ ...prev, options: newOrder.map((index) => prev.options[index]) }));
19
+ }, [setState]);
20
+ const draggable = options.length > 1;
21
+ return (React.createElement("fieldset", { className: 'str-chat__form__field str-chat__form__input-fieldset' },
22
+ React.createElement("legend", { className: 'str-chat__form__field-label' }, t('Options')),
23
+ React.createElement(DragAndDropContainer, { className: 'str-chat__form__input-fieldset__values', draggable: draggable, onSetNewOrder: onSetNewOrder }, options.map((option, i) => (React.createElement("div", { className: clsx('str-chat__form__input-field', {
24
+ 'str-chat__form__input-field--draggable': draggable,
25
+ 'str-chat__form__input-field--has-error': errors[option.id],
26
+ }), key: `new-poll-option-${i}` },
27
+ React.createElement("div", { className: 'str-chat__form__input-field__value' },
28
+ React.createElement(FieldError, { className: 'str-chat__form__input-field__error', "data-testid": 'poll-option-input-field-error', text: errors[option.id] }),
29
+ React.createElement("input", { id: option.id, onBlur: (e) => {
30
+ if (findOptionDuplicate({ id: e.target.id, text: e.target.value })) {
31
+ setErrors((prev) => ({
32
+ ...prev,
33
+ [e.target.id]: t('Option already exists'),
34
+ }));
35
+ }
36
+ }, onChange: (e) => {
37
+ setState((prev) => {
38
+ const shouldAddEmptyOption = prev.options.length < MAX_POLL_OPTIONS &&
39
+ (!prev.options ||
40
+ (prev.options.slice(i + 1).length === 0 && !!e.target.value));
41
+ const shouldRemoveOption = prev.options && prev.options.slice(i + 1).length > 0 && !e.target.value;
42
+ const optionListHead = prev.options ? prev.options.slice(0, i) : [];
43
+ const optionListTail = shouldAddEmptyOption
44
+ ? [{ id: nanoid(), text: '' }]
45
+ : (prev.options || []).slice(i + 1);
46
+ if ((errors[option.id] && !e.target.value) ||
47
+ (VALIDATION_ERRORS[errors[option.id]] &&
48
+ !findOptionDuplicate({ id: e.target.id, text: e.target.value }))) {
49
+ setErrors((prev) => {
50
+ delete prev[option.id];
51
+ return prev;
52
+ });
53
+ }
54
+ return {
55
+ ...prev,
56
+ options: [
57
+ ...optionListHead,
58
+ ...(shouldRemoveOption ? [] : [{ ...option, text: e.target.value }]),
59
+ ...optionListTail,
60
+ ],
61
+ };
62
+ });
63
+ }, onKeyUp: (event) => {
64
+ if (event.key === 'Enter') {
65
+ const nextInputId = options[i + 1].id;
66
+ document.getElementById(nextInputId)?.focus();
67
+ }
68
+ }, placeholder: t('Add an option'), type: 'text', value: option.text })),
69
+ draggable && React.createElement("div", { className: 'str-chat__drag-handle' })))))));
70
+ };
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ export type PollCreationDialogProps = {
3
+ close: () => void;
4
+ };
5
+ export declare const PollCreationDialog: ({ close }: PollCreationDialogProps) => React.JSX.Element;