diff --git a/package/src/components/Channel/Channel.tsx b/package/src/components/Channel/Channel.tsx index 5e8cba928e..e0d6481136 100644 --- a/package/src/components/Channel/Channel.tsx +++ b/package/src/components/Channel/Channel.tsx @@ -852,13 +852,7 @@ const ChannelWithContext = < setThreadMessages(updatedThreadMessages); } - if ( - channel && - thread?.id && - event.message?.id === thread.id && - !threadInstance && - !thread.poll_id - ) { + if (channel && thread?.id && event.message?.id === thread.id && !threadInstance) { const updatedThread = channel.state.formatMessage(event.message); setThread(updatedThread); } diff --git a/package/src/components/ChannelPreview/hooks/useLatestMessagePreview.ts b/package/src/components/ChannelPreview/hooks/useLatestMessagePreview.ts index a1ef491b79..cc43a21768 100644 --- a/package/src/components/ChannelPreview/hooks/useLatestMessagePreview.ts +++ b/package/src/components/ChannelPreview/hooks/useLatestMessagePreview.ts @@ -40,6 +40,7 @@ export type LatestMessagePreview< export type LatestMessagePreviewSelectorReturnType = { createdBy?: UserResponse | null; latestVotesByOption?: Record; + name?: string; }; const selector = ( @@ -47,6 +48,7 @@ const selector = ({ createdBy: nextValue.created_by, latestVotesByOption: nextValue.latest_votes_by_option, + name: nextValue.name, }); const getMessageSenderName = < @@ -145,8 +147,8 @@ const getLatestMessageDisplayText = < { bold: false, text: t('🏙 Attachment...') }, ]; } - if (message.poll && pollState) { - const { createdBy, latestVotesByOption } = pollState; + if (message.poll_id && pollState) { + const { createdBy, latestVotesByOption, name } = pollState; let latestVotes; if (latestVotesByOption) { latestVotes = Object.values(latestVotesByOption) @@ -161,7 +163,7 @@ const getLatestMessageDisplayText = < } const previewMessage = `${ client.userID === previewUser?.id ? 'You' : previewUser?.name - } ${previewAction}: ${message.poll.name}`; + } ${previewAction}: ${name}`; return [ { bold: false, text: '📊 ' }, { bold: false, text: previewMessage }, @@ -311,7 +313,7 @@ export const useLatestMessagePreview = < const poll = client.polls.fromState(pollId); const pollState: LatestMessagePreviewSelectorReturnType = useStateStore(poll?.state, selector) ?? {}; - const { createdBy, latestVotesByOption } = pollState; + const { createdBy, latestVotesByOption, name } = pollState; useEffect( () => @@ -326,7 +328,15 @@ export const useLatestMessagePreview = < }), ), // eslint-disable-next-line react-hooks/exhaustive-deps - [channelLastMessageString, forceUpdate, readEvents, readStatus, latestVotesByOption, createdBy], + [ + channelLastMessageString, + forceUpdate, + readEvents, + readStatus, + latestVotesByOption, + createdBy, + name, + ], ); return latestMessagePreview; diff --git a/package/src/components/Chat/hooks/handleEventToSyncDB.ts b/package/src/components/Chat/hooks/handleEventToSyncDB.ts index 6734645e7c..b8a6b25d25 100644 --- a/package/src/components/Chat/hooks/handleEventToSyncDB.ts +++ b/package/src/components/Chat/hooks/handleEventToSyncDB.ts @@ -233,11 +233,14 @@ export const handleEventToSyncDB = < 'poll.vote_removed', ].includes(type) ) { - const poll = event.poll; + const { poll, poll_vote, type } = event; if (poll) { return updatePollMessage({ + eventType: type, flush, poll, + poll_vote, + userID: client?.userID || '', }); } } diff --git a/package/src/components/Message/MessageSimple/MessageContent.tsx b/package/src/components/Message/MessageSimple/MessageContent.tsx index 4a6a20fe9d..977d2c4554 100644 --- a/package/src/components/Message/MessageSimple/MessageContent.tsx +++ b/package/src/components/Message/MessageSimple/MessageContent.tsx @@ -149,7 +149,7 @@ const MessageContentWithContext = < const { theme: { - colors: { blue_alice, grey_gainsboro, grey_whisper, transparent, white }, + colors: { blue_alice, grey_whisper, light_gray, transparent, white_snow }, messageSimple: { content: { container: { @@ -214,20 +214,20 @@ const MessageContentWithContext = < const isMessageReceivedOrErrorType = !isMyMessage || error; - let backgroundColor = senderMessageBackgroundColor || grey_gainsboro; + let backgroundColor = senderMessageBackgroundColor ?? light_gray; if (onlyEmojis && !message.quoted_message) { backgroundColor = transparent; } else if (otherAttachments.length) { if (otherAttachments[0].type === 'giphy') { - backgroundColor = message.quoted_message ? grey_gainsboro : transparent; + backgroundColor = message.quoted_message ? light_gray : transparent; } else { backgroundColor = blue_alice; } } else if (isMessageReceivedOrErrorType) { - backgroundColor = receiverMessageBackgroundColor || white; + backgroundColor = receiverMessageBackgroundColor ?? white_snow; } - const repliesCurveColor = !isMessageReceivedOrErrorType ? backgroundColor : grey_gainsboro; + const repliesCurveColor = !isMessageReceivedOrErrorType ? backgroundColor : light_gray; const getBorderRadius = () => { // enum('top', 'middle', 'bottom', 'single') diff --git a/package/src/components/Message/MessageSimple/MessageReplies.tsx b/package/src/components/Message/MessageSimple/MessageReplies.tsx index c98a82df0d..9f3092bf23 100644 --- a/package/src/components/Message/MessageSimple/MessageReplies.tsx +++ b/package/src/components/Message/MessageSimple/MessageReplies.tsx @@ -32,7 +32,7 @@ const styles = StyleSheet.create({ }, messageRepliesCurve: { borderTopWidth: 0, - borderWidth: 1, + borderWidth: 2, height: 16, width: 16, }, @@ -181,6 +181,7 @@ const areEqual = { {t('Multiple answers')} setMultipleAnswersAllowed(!multipleAnswersAllowed)} + onValueChange={() => { + if (multipleAnswersAllowed) { + setMaxVotesPerPersonEnabled(false); + } + setMultipleAnswersAllowed(!multipleAnswersAllowed); + }} value={multipleAnswersAllowed} /> diff --git a/package/src/components/Reply/Reply.tsx b/package/src/components/Reply/Reply.tsx index 83ead74468..7dbc7d62d8 100644 --- a/package/src/components/Reply/Reply.tsx +++ b/package/src/components/Reply/Reply.tsx @@ -6,8 +6,9 @@ import dayjs from 'dayjs'; import merge from 'lodash/merge'; -import type { Attachment } from 'stream-chat'; +import type { Attachment, PollState } from 'stream-chat'; +import { useChatContext } from '../../contexts'; import { useMessageContext } from '../../contexts/messageContext/MessageContext'; import { MessageInputContext, @@ -22,6 +23,7 @@ import { TranslationContextValue, useTranslationContext, } from '../../contexts/translationContext/TranslationContext'; +import { useStateStore } from '../../hooks'; import { DefaultStreamChatGenerics, FileTypes } from '../../types/types'; import { getResizedImageUrl } from '../../utils/getResizedImageUrl'; import { getTrimmedAttachmentTitle } from '../../utils/getTrimmedAttachmentTitle'; @@ -31,6 +33,7 @@ import { FileIcon as FileIconDefault } from '../Attachment/FileIcon'; import { VideoThumbnail } from '../Attachment/VideoThumbnail'; import { MessageAvatar as MessageAvatarDefault } from '../Message/MessageSimple/MessageAvatar'; import { MessageTextContainer } from '../Message/MessageSimple/MessageTextContainer'; +import { MessageType } from '../MessageList/hooks/useMessageList'; const styles = StyleSheet.create({ container: { @@ -72,6 +75,16 @@ const styles = StyleSheet.create({ }, }); +export type ReplySelectorReturnType = { + name?: string; +}; + +const selector = ( + nextValue: PollState, +): ReplySelectorReturnType => ({ + name: nextValue.name, +}); + type ReplyPropsWithContext< StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, > = Pick, 'quotedMessage'> & @@ -134,6 +147,7 @@ const ReplyWithContext = < >( props: ReplyPropsWithContext, ) => { + const { client } = useChatContext(); const { attachmentSize = 40, FileAttachmentIcon, @@ -167,6 +181,9 @@ const ReplyWithContext = < }, } = useTheme(); + const poll = client.polls.fromState((quotedMessage as MessageType)?.poll_id ?? ''); + const { name: pollName }: ReplySelectorReturnType = useStateStore(poll?.state, selector) ?? {}; + const messageText = typeof quotedMessage === 'boolean' ? '' : quotedMessage.text || ''; const emojiOnlyText = useMemo(() => { @@ -262,8 +279,8 @@ const ReplyWithContext = < text: quotedMessage.type === 'deleted' ? `_${t('Message deleted')}_` - : quotedMessage.poll - ? `📊 ${quotedMessage.poll.name}` + : pollName + ? `📊 ${pollName}` : quotedMessage.text ? quotedMessage.text.length > 170 ? `${quotedMessage.text.slice(0, 170)}...` diff --git a/package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap b/package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap index 5f63002d17..8622e18f8f 100644 --- a/package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +++ b/package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap @@ -416,7 +416,7 @@ exports[`Thread should match thread snapshot 1`] = ` "overflow": "hidden", }, { - "backgroundColor": "#F2F2F2", + "backgroundColor": "#FCFCFC", "borderBottomLeftRadius": 0, "borderBottomRightRadius": 16, "borderColor": "#ECEBEB", @@ -742,7 +742,7 @@ exports[`Thread should match thread snapshot 1`] = ` "overflow": "hidden", }, { - "backgroundColor": "#F2F2F2", + "backgroundColor": "#FCFCFC", "borderBottomLeftRadius": 0, "borderBottomRightRadius": 16, "borderColor": "#ECEBEB", @@ -1068,7 +1068,7 @@ exports[`Thread should match thread snapshot 1`] = ` "overflow": "hidden", }, { - "backgroundColor": "#F2F2F2", + "backgroundColor": "#FCFCFC", "borderBottomLeftRadius": 0, "borderBottomRightRadius": 16, "borderColor": "#ECEBEB", @@ -1422,7 +1422,7 @@ exports[`Thread should match thread snapshot 1`] = ` "overflow": "hidden", }, { - "backgroundColor": "#F2F2F2", + "backgroundColor": "#FCFCFC", "borderBottomLeftRadius": 0, "borderBottomRightRadius": 16, "borderColor": "#ECEBEB", diff --git a/package/src/contexts/themeContext/utils/theme.ts b/package/src/contexts/themeContext/utils/theme.ts index 0784cfa111..9e380e064c 100644 --- a/package/src/contexts/themeContext/utils/theme.ts +++ b/package/src/contexts/themeContext/utils/theme.ts @@ -1218,10 +1218,8 @@ export const defaultTheme: Theme = { metaText: { fontSize: 12, }, - receiverMessageBackgroundColor: Colors.white_smoke, replyBorder: {}, replyContainer: {}, - senderMessageBackgroundColor: Colors.grey_gainsboro, textContainer: { onlyEmojiMarkdown: { text: { fontSize: 50 } }, }, diff --git a/package/src/store/QuickSqliteClient.ts b/package/src/store/QuickSqliteClient.ts index 6d07a8e34c..960a734a36 100644 --- a/package/src/store/QuickSqliteClient.ts +++ b/package/src/store/QuickSqliteClient.ts @@ -30,7 +30,7 @@ import type { PreparedQueries, Table } from './types'; * */ export class QuickSqliteClient { - static dbVersion = 6; + static dbVersion = 7; static dbName = DB_NAME; static dbLocation = DB_LOCATION; diff --git a/package/src/store/apis/getChannelMessages.ts b/package/src/store/apis/getChannelMessages.ts index 3d1b0557bc..2158a1528a 100644 --- a/package/src/store/apis/getChannelMessages.ts +++ b/package/src/store/apis/getChannelMessages.ts @@ -8,7 +8,8 @@ import type { DefaultStreamChatGenerics } from '../../types/types'; import { isBlockedMessage } from '../../utils/utils'; import { mapStorableToMessage } from '../mappers/mapStorableToMessage'; import { QuickSqliteClient } from '../QuickSqliteClient'; -import type { TableRowJoinedUser } from '../types'; +import { createSelectQuery } from '../sqlite-utils/createSelectQuery'; +import type { TableRow, TableRowJoinedUser } from '../types'; export const getChannelMessages = < StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, @@ -35,6 +36,21 @@ export const getChannelMessages = < } messageIdVsReactions[reaction.messageId].push(reaction); }); + const messageIdsVsPolls: Record> = {}; + const pollsById: Record> = {}; + const messagesWithPolls = messageRows.filter((message) => !!message.poll_id); + const polls = QuickSqliteClient.executeSql.apply( + null, + createSelectQuery('poll', ['*'], { + id: messagesWithPolls.map((message) => message.poll_id), + }), + ); + polls.forEach((poll) => { + pollsById[poll.id] = poll; + }); + messagesWithPolls.forEach((message) => { + messageIdsVsPolls[message.poll_id] = pollsById[message.poll_id]; + }); // Populate the messages. const cidVsMessages: Record[]> = {}; @@ -48,6 +64,7 @@ export const getChannelMessages = < mapStorableToMessage({ currentUserId, messageRow: m, + pollRow: messageIdsVsPolls[m.poll_id], reactionRows: messageIdVsReactions[m.id], }), ); diff --git a/package/src/store/apis/updateMessage.ts b/package/src/store/apis/updateMessage.ts index 0ac4145b62..e89d6fecc7 100644 --- a/package/src/store/apis/updateMessage.ts +++ b/package/src/store/apis/updateMessage.ts @@ -30,7 +30,9 @@ export const updateMessage = ({ return queries; } - const storableMessage = mapMessageToStorable(message); + const storableMessage = mapMessageToStorable({ + ...message, + }); queries.push( createUpdateQuery('messages', storableMessage, { diff --git a/package/src/store/apis/updatePollMessage.ts b/package/src/store/apis/updatePollMessage.ts index c3b8c04695..affabd2d97 100644 --- a/package/src/store/apis/updatePollMessage.ts +++ b/package/src/store/apis/updatePollMessage.ts @@ -1,41 +1,67 @@ -import type { PollResponse } from 'stream-chat'; +import { isVoteAnswer, PollAnswer, PollResponse, PollVote } from 'stream-chat'; +import { DefaultStreamChatGenerics } from '../../types/types'; +import { mapPollToStorable } from '../mappers/mapPollToStorable'; +import { mapStorableToPoll } from '../mappers/mapStorableToPoll'; import { QuickSqliteClient } from '../QuickSqliteClient'; import { createSelectQuery } from '../sqlite-utils/createSelectQuery'; import { createUpdateQuery } from '../sqlite-utils/createUpdateQuery'; import type { PreparedQueries } from '../types'; -export const updatePollMessage = ({ +export const updatePollMessage = < + StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, +>({ + eventType, flush = true, poll, + poll_vote, + userID, }: { - poll: PollResponse; + eventType: string; + poll: PollResponse; + userID: string; flush?: boolean; + poll_vote?: PollVote | PollAnswer; }) => { const queries: PreparedQueries[] = []; - const messagesWithPoll = QuickSqliteClient.executeSql.apply( + const pollsFromDB = QuickSqliteClient.executeSql.apply( null, - createSelectQuery('messages', ['*'], { - poll_id: poll.id, + createSelectQuery('poll', ['*'], { + id: poll.id, }), ); - for (const message of messagesWithPoll) { - const storablePoll = JSON.stringify({ + for (const pollFromDB of pollsFromDB) { + const serializedPoll = mapStorableToPoll(pollFromDB); + const { latest_answers = [], own_votes = [] } = serializedPoll; + let newOwnVotes = own_votes; + if (poll_vote && poll_vote.user?.id === userID) { + newOwnVotes = + eventType === 'poll.vote_removed' + ? newOwnVotes.filter((vote) => vote.id !== poll_vote.id) + : [poll_vote, ...newOwnVotes.filter((vote) => vote.id !== poll_vote.id)]; + } + let newLatestAnswers = latest_answers; + if (poll_vote && isVoteAnswer(poll_vote)) { + newLatestAnswers = + eventType === 'poll.vote_removed' + ? newLatestAnswers.filter((answer) => answer.id !== poll_vote?.id) + : [poll_vote, ...newLatestAnswers.filter((answer) => answer.id !== poll_vote?.id)]; + } + + const storablePoll = mapPollToStorable({ ...poll, - latest_votes: message.poll.latest_votes, - own_votes: message.poll.own_votes, + latest_answers: newLatestAnswers, + own_votes: newOwnVotes, }); - const storableMessage = { ...message, poll: storablePoll }; queries.push( - createUpdateQuery('messages', storableMessage, { - id: message.id, + createUpdateQuery('poll', storablePoll, { + id: poll.id, }), ); QuickSqliteClient.logger?.('info', 'updatePoll', { - message: storableMessage, poll: storablePoll, }); } diff --git a/package/src/store/apis/upsertMessages.ts b/package/src/store/apis/upsertMessages.ts index 0077131067..5748e47358 100644 --- a/package/src/store/apis/upsertMessages.ts +++ b/package/src/store/apis/upsertMessages.ts @@ -1,6 +1,7 @@ import type { MessageResponse } from 'stream-chat'; import { mapMessageToStorable } from '../mappers/mapMessageToStorable'; +import { mapPollToStorable } from '../mappers/mapPollToStorable'; import { mapReactionToStorable } from '../mappers/mapReactionToStorable'; import { mapUserToStorable } from '../mappers/mapUserToStorable'; import { QuickSqliteClient } from '../QuickSqliteClient'; @@ -16,6 +17,7 @@ export const upsertMessages = ({ const storableMessages: Array> = []; const storableUsers: Array> = []; const storableReactions: Array> = []; + const storablePolls: Array> = []; messages?.forEach((message: MessageResponse) => { storableMessages.push(mapMessageToStorable(message)); @@ -28,6 +30,9 @@ export const upsertMessages = ({ } storableReactions.push(mapReactionToStorable(r)); }); + if (message.poll) { + storablePolls.push(mapPollToStorable(message.poll)); + } }); const finalQueries = [ @@ -36,11 +41,13 @@ export const upsertMessages = ({ ...storableReactions.map((storableReaction) => createUpsertQuery('reactions', storableReaction), ), + ...storablePolls.map((storablePoll) => createUpsertQuery('poll', storablePoll)), ]; QuickSqliteClient.logger?.('info', 'upsertMessages', { flush, messages: storableMessages, + polls: storablePolls, reactions: storableReactions, users: storableUsers, }); diff --git a/package/src/store/mappers/mapMessageToStorable.ts b/package/src/store/mappers/mapMessageToStorable.ts index 3caac21ba4..e8f4484eef 100644 --- a/package/src/store/mappers/mapMessageToStorable.ts +++ b/package/src/store/mappers/mapMessageToStorable.ts @@ -18,6 +18,7 @@ export const mapMessageToStorable = ( message_text_updated_at, // eslint-disable-next-line @typescript-eslint/no-unused-vars own_reactions, + // eslint-disable-next-line @typescript-eslint/no-unused-vars poll, poll_id, reaction_groups, @@ -36,7 +37,6 @@ export const mapMessageToStorable = ( extraData: JSON.stringify(extraData), id, messageTextUpdatedAt: mapDateTimeToStorable(message_text_updated_at), - poll: JSON.stringify(poll), poll_id: poll_id || '', reactionGroups: JSON.stringify(reaction_groups), text, diff --git a/package/src/store/mappers/mapPollToStorable.ts b/package/src/store/mappers/mapPollToStorable.ts new file mode 100644 index 0000000000..fb9ea75bd5 --- /dev/null +++ b/package/src/store/mappers/mapPollToStorable.ts @@ -0,0 +1,53 @@ +import type { PollResponse } from 'stream-chat'; + +import { mapDateTimeToStorable } from './mapDateTimeToStorable'; + +import type { TableRow } from '../types'; + +export const mapPollToStorable = (poll: PollResponse): TableRow<'poll'> => { + const { + allow_answers, + allow_user_suggested_options, + answers_count, + created_at, + created_by, + created_by_id, + description, + enforce_unique_vote, + id, + is_closed, + latest_answers, + latest_votes_by_option, + max_votes_allowed, + name, + options, + own_votes, + updated_at, + vote_count, + vote_counts_by_option, + voting_visibility, + } = poll; + + return { + allow_answers, + allow_user_suggested_options, + answers_count, + created_at: mapDateTimeToStorable(created_at), + created_by: JSON.stringify(created_by), // decouple the users from the actual poll + created_by_id, + description, + enforce_unique_vote, + id, + is_closed, + latest_answers: JSON.stringify(latest_answers), + latest_votes_by_option: JSON.stringify(latest_votes_by_option), + max_votes_allowed, + name, + options: JSON.stringify(options), + own_votes: JSON.stringify(own_votes), + updated_at, + vote_count, + vote_counts_by_option: JSON.stringify(vote_counts_by_option), + voting_visibility, + }; +}; diff --git a/package/src/store/mappers/mapStorableToMessage.ts b/package/src/store/mappers/mapStorableToMessage.ts index b1ae3fa01a..45d34d1734 100644 --- a/package/src/store/mappers/mapStorableToMessage.ts +++ b/package/src/store/mappers/mapStorableToMessage.ts @@ -1,22 +1,25 @@ import type { MessageResponse } from 'stream-chat'; +import { mapStorableToPoll } from './mapStorableToPoll'; import { mapStorableToReaction } from './mapStorableToReaction'; import { mapStorableToUser } from './mapStorableToUser'; import type { DefaultStreamChatGenerics } from '../../types/types'; -import type { TableRowJoinedUser } from '../types'; +import type { TableRow, TableRowJoinedUser } from '../types'; export const mapStorableToMessage = < StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, >({ currentUserId, messageRow, + pollRow, reactionRows, }: { currentUserId: string; messageRow: TableRowJoinedUser<'messages'>; + pollRow: TableRow<'poll'>; reactionRows: TableRowJoinedUser<'reactions'>[]; }): MessageResponse => { const { @@ -24,7 +27,6 @@ export const mapStorableToMessage = < deletedAt, extraData, messageTextUpdatedAt, - poll, poll_id, reactionGroups, updatedAt, @@ -44,11 +46,11 @@ export const mapStorableToMessage = < latest_reactions: latestReactions, message_text_updated_at: messageTextUpdatedAt, own_reactions: ownReactions, - poll: JSON.parse(poll), poll_id, reaction_groups: reactionGroups ? JSON.parse(reactionGroups) : {}, updated_at: updatedAt, user: mapStorableToUser(user), + ...(pollRow ? { poll: mapStorableToPoll(pollRow) } : {}), ...(extraData ? JSON.parse(extraData) : {}), }; }; diff --git a/package/src/store/mappers/mapStorableToPoll.ts b/package/src/store/mappers/mapStorableToPoll.ts new file mode 100644 index 0000000000..ffeb1ad2de --- /dev/null +++ b/package/src/store/mappers/mapStorableToPoll.ts @@ -0,0 +1,56 @@ +import { PollResponse, VotingVisibility } from 'stream-chat'; + +import type { DefaultStreamChatGenerics } from '../../types/types'; +import type { TableRow } from '../types'; + +export const mapStorableToPoll = < + StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics, +>( + pollRow: TableRow<'poll'>, +): PollResponse => { + const { + allow_answers, + allow_user_suggested_options, + answers_count, + created_at, + created_by, + created_by_id, + description, + enforce_unique_vote, + id, + is_closed, + latest_answers, + latest_votes_by_option, + max_votes_allowed, + name, + options, + own_votes, + updated_at, + vote_count, + vote_counts_by_option, + voting_visibility, + } = pollRow; + + return { + allow_answers, + allow_user_suggested_options, + answers_count, + created_at, + created_by: JSON.parse(created_by), + created_by_id, + description, + enforce_unique_vote, + id, + is_closed, + latest_answers: JSON.parse(latest_answers), + latest_votes_by_option: JSON.parse(latest_votes_by_option), + max_votes_allowed, + name, + options: JSON.parse(options), + own_votes: own_votes ? JSON.parse(own_votes) : [], + updated_at, + vote_count, + vote_counts_by_option: JSON.parse(vote_counts_by_option), + voting_visibility: voting_visibility as VotingVisibility | undefined, + }; +}; diff --git a/package/src/store/schema.ts b/package/src/store/schema.ts index 995b423510..be894f1667 100644 --- a/package/src/store/schema.ts +++ b/package/src/store/schema.ts @@ -103,7 +103,6 @@ export const tables: Tables = { extraData: 'TEXT', id: 'TEXT', messageTextUpdatedAt: 'TEXT', - poll: 'TEXT', poll_id: 'TEXT', reactionGroups: 'TEXT', text: "TEXT DEFAULT ''", @@ -139,6 +138,31 @@ export const tables: Tables = { type: 'TEXT', }, }, + poll: { + columns: { + allow_answers: 'BOOLEAN DEFAULT FALSE', + allow_user_suggested_options: 'BOOLEAN DEFAULT FALSE', + answers_count: 'INTEGER DEFAULT 0', + created_at: 'TEXT', + created_by: 'TEXT', + created_by_id: 'TEXT', + description: 'TEXT', + enforce_unique_vote: 'BOOLEAN DEFAULT FALSE', + id: 'TEXT NOT NULL', + is_closed: 'BOOLEAN DEFAULT FALSE', + latest_answers: 'TEXT', + latest_votes_by_option: 'TEXT', + max_votes_allowed: 'INTEGER DEFAULT 1', + name: 'TEXT', + options: 'TEXT', + own_votes: 'TEXT', + updated_at: 'TEXT', + vote_count: 'INTEGER DEFAULT 0', + vote_counts_by_option: 'TEXT', + voting_visibility: 'TEXT', + }, + primaryKey: ['id'], + }, reactions: { columns: { createdAt: 'TEXT', @@ -266,7 +290,6 @@ export type Schema = { extraData: string; id: string; messageTextUpdatedAt: string; - poll: string; poll_id: string; reactionGroups: string; type: MessageLabel; @@ -283,6 +306,28 @@ export type Schema = { payload: string; type: ValueOf; }; + poll: { + answers_count: number; + created_at: string; + created_by: string; + created_by_id: string; + enforce_unique_vote: boolean; + id: string; + latest_answers: string; + latest_votes_by_option: string; + max_votes_allowed: number; + name: string; + options: string; + updated_at: string; + vote_count: number; + vote_counts_by_option: string; + allow_answers?: boolean; + allow_user_suggested_options?: boolean; + description?: string; + is_closed?: boolean; + own_votes?: string; + voting_visibility?: string; + }; reactions: { createdAt: string; messageId: string;