@cometchat/chat-uikit-react
Version:
Ready-to-use Chat UI Components for React
277 lines (272 loc) • 11.6 kB
JavaScript
'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;