UNPKG

@cometchat/chat-uikit-react

Version:

Ready-to-use Chat UI Components for React

277 lines (272 loc) 11.6 kB
'use strict'; var chunkMGBDQDQV_cjs = require('./chunk-MGBDQDQV.cjs'); var chunkFP33MEDB_cjs = require('./chunk-FP33MEDB.cjs'); var chunk4ZJVM6IL_cjs = require('./chunk-4ZJVM6IL.cjs'); var chunkKMTY4OFY_cjs = require('./chunk-KMTY4OFY.cjs'); var react = require('react'); var chatSdkJavascript = require('@cometchat/chat-sdk-javascript'); var jsxRuntime = require('react/jsx-runtime'); require('./index.css'); // src/components/CometChatPollBubble/polls.utils.ts function extractPollData(message) { if (!message) return null; try { const metadata = message.getMetadata(); if (!metadata) return null; const injected = metadata[chunkMGBDQDQV_cjs.POLLS_CONSTANTS.injectedKey]; if (!injected) return null; const extensions = injected[chunkMGBDQDQV_cjs.POLLS_CONSTANTS.extensionsKey]; if (!extensions) return null; const pollsData = extensions[chunkMGBDQDQV_cjs.POLLS_CONSTANTS.pollsKey]; if (!pollsData) return null; return { id: pollsData.id || message.getId(), question: pollsData.question || "", options: pollsData.options || {}, results: pollsData.results || { total: 0, options: {} } }; } catch { return null; } } function processPollOptions(pollData, loggedInUserUid) { const totalVotes = pollData.results.total || 0; const optionKeys = Object.keys(pollData.options); return optionKeys.map((optionId) => { const optionResult = pollData.results.options[optionId]; const voteCount = optionResult?.count ?? 0; const percentage = totalVotes > 0 ? Math.round(voteCount / totalVotes * 100) : 0; const selectedByLoggedInUser = loggedInUserUid ? Object.prototype.hasOwnProperty.call(optionResult?.voters ?? {}, loggedInUserUid) : false; const voters = optionResult?.voters ? Object.values(optionResult.voters).slice(0, 3) : []; return { id: optionId, text: pollData.options[optionId] ?? "", count: voteCount, percent: `${String(percentage)}%`, selectedByLoggedInUser, voters }; }); } var CometChatPollBubble = ({ message, alignment, disableInteraction = false, onVoteSubmit, onVoteError, className }) => { const { getLocalizedString } = chunkKMTY4OFY_cjs.useLocale(); const loggedInUser = chunk4ZJVM6IL_cjs.useLoggedInUser(); const isOutgoing = (alignment ?? chunkFP33MEDB_cjs.getBubbleAlignment(message, loggedInUser)) === "right"; const loggedInUserUid = loggedInUser?.getUid(); const initialPollData = react.useMemo(() => extractPollData(message), [message]); const [pollData, setPollData] = react.useState(initialPollData); const [announcement, setAnnouncement] = react.useState(""); react.useEffect(() => { const newData = extractPollData(message); if (newData) { setPollData(newData); } }, [message]); const pollOptions = react.useMemo( () => pollData ? processPollOptions(pollData, loggedInUserUid) : [], [pollData, loggedInUserUid] ); const handleOptionClick = react.useCallback( (option) => { if (disableInteraction || !pollData) return; const previousPollData = pollData; const newResults = { ...pollData.results }; newResults.options = { ...newResults.options }; const previouslySelected = pollOptions.find((opt) => opt.selectedByLoggedInUser); if (previouslySelected && previouslySelected.id !== option.id) { const prevResult = newResults.options[previouslySelected.id]; if (prevResult) { if (loggedInUserUid) { const { [loggedInUserUid]: _removed, ...rest } = prevResult.voters; newResults.options[previouslySelected.id] = { ...prevResult, count: Math.max(0, prevResult.count - 1), voters: rest }; } else { newResults.options[previouslySelected.id] = { ...prevResult, count: Math.max(0, prevResult.count - 1), voters: { ...prevResult.voters } }; } } newResults.total = Math.max(0, newResults.total - 1); } if (previouslySelected?.id !== option.id && loggedInUserUid) { const selectedResult = newResults.options[option.id] ?? { count: 0, voters: {} }; newResults.options[option.id] = { ...selectedResult, count: selectedResult.count + 1, voters: { ...selectedResult.voters, [loggedInUserUid]: { name: loggedInUser?.getName() ?? "", avatar: loggedInUser?.getAvatar() } } }; newResults.total = newResults.total + 1; } setPollData({ ...pollData, results: newResults }); chatSdkJavascript.CometChat.callExtension( chunkMGBDQDQV_cjs.POLLS_CONSTANTS.extensionName, chunkMGBDQDQV_cjs.POLLS_CONSTANTS.postMethod, chunkMGBDQDQV_cjs.POLLS_CONSTANTS.voteEndpoint, { vote: option.id, id: pollData.id } ).then(() => { onVoteSubmit?.({ pollId: pollData.id, optionId: option.id, optionText: option.text, message }); setAnnouncement(`Vote submitted for ${option.text}`); }).catch((error) => { setPollData(previousPollData); onVoteError?.({ pollId: pollData.id, optionId: option.id, error: error instanceof Error ? error : new Error(String(error)), message }); }); }, [ disableInteraction, pollData, pollOptions, loggedInUserUid, loggedInUser, message, onVoteSubmit, onVoteError ] ); const handleOptionKeyDown = react.useCallback( (event, option) => { if (event.key === "Enter" || event.key === " ") { event.preventDefault(); handleOptionClick(option); } }, [handleOptionClick] ); if (!pollData) return null; const variantClass = isOutgoing ? "cometchat-poll-bubble--outgoing" : "cometchat-poll-bubble--incoming"; const rootClasses = ["cometchat-poll-bubble", variantClass, className].filter(Boolean).join(" "); return /* @__PURE__ */ jsxRuntime.jsxs( "div", { className: rootClasses, role: "group", "aria-label": getLocalizedString("accessibility_poll_question").replace( "{question}", pollData.question ), children: [ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cometchat-poll-bubble__question", children: pollData.question }), /* @__PURE__ */ jsxRuntime.jsx( "ul", { className: "cometchat-poll-bubble__options", role: "radiogroup", "aria-label": getLocalizedString("accessibility_poll_options"), children: pollOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsxs( "li", { className: "cometchat-poll-bubble__option", role: "radio", "aria-checked": option.selectedByLoggedInUser, "aria-label": `${option.text}, ${getLocalizedString("accessibility_vote_count").replace("{count}", String(option.count))}, ${option.percent}`, tabIndex: disableInteraction ? -1 : 0, onClick: () => { handleOptionClick(option); }, onKeyDown: (e) => { handleOptionKeyDown(e, option); }, children: [ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cometchat-poll-bubble__option-radio", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx( "div", { className: [ "cometchat-poll-bubble__option-radio-circle", option.selectedByLoggedInUser ? "cometchat-poll-bubble__option-radio-circle--selected" : "" ].filter(Boolean).join(" ") } ) }), /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cometchat-poll-bubble__option-body", children: [ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cometchat-poll-bubble__option-content", children: [ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cometchat-poll-bubble__option-text", children: option.text }), /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cometchat-poll-bubble__option-tail", "aria-hidden": "true", children: [ option.voters.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cometchat-poll-bubble__option-avatars", children: option.voters.map((voter, index) => { const isLast = index === option.voters.length - 1; return /* @__PURE__ */ jsxRuntime.jsx( "div", { className: [ "cometchat-poll-bubble__option-avatar", isLast ? "cometchat-poll-bubble__option-avatar--last" : "" ].filter(Boolean).join(" "), style: { zIndex: index }, children: voter.avatar ? /* @__PURE__ */ jsxRuntime.jsx( "img", { src: voter.avatar, alt: voter.name, loading: "lazy", decoding: "async" } ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cometchat-poll-bubble__option-avatar-initials", children: voter.name.charAt(0).toUpperCase() }) }, index ); }) }), /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cometchat-poll-bubble__option-count", children: option.count }) ] }) ] }), /* @__PURE__ */ jsxRuntime.jsx( "div", { className: "cometchat-poll-bubble__option-progress", role: "progressbar", "aria-valuenow": parseInt(option.percent), "aria-valuemin": 0, "aria-valuemax": 100, "aria-label": getLocalizedString("accessibility_of_votes").replace( "{percent}", option.percent ), children: /* @__PURE__ */ jsxRuntime.jsx( "div", { className: "cometchat-poll-bubble__option-progress-bar", style: { width: option.percent } } ) } ) ] }) ] }, option.id )) } ), /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-live": "polite", "aria-atomic": "true", className: "cometchat-poll-bubble__sr-only", children: announcement }) ] } ); }; CometChatPollBubble.displayName = "CometChatPollBubble"; var CometChatPollBubble_default = CometChatPollBubble; exports.CometChatPollBubble = CometChatPollBubble; exports.CometChatPollBubble_default = CometChatPollBubble_default;