@selfcommunity/react-ui
Version:
React UI Components to integrate a Community created with SelfCommunity Platform.
170 lines (160 loc) • 11 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const styles_1 = require("@mui/material/styles");
const material_1 = require("@mui/material");
const Skeleton_1 = tslib_1.__importDefault(require("./Skeleton"));
const react_intl_1 = require("react-intl");
const types_1 = require("@selfcommunity/types");
const Icon_1 = tslib_1.__importDefault(require("@mui/material/Icon"));
const classnames_1 = tslib_1.__importDefault(require("classnames"));
const system_1 = require("@mui/system");
const react_core_1 = require("@selfcommunity/react-core");
const useMediaQuery_1 = tslib_1.__importDefault(require("@mui/material/useMediaQuery"));
const PrivateMessageSettingsIconButton_1 = tslib_1.__importDefault(require("../PrivateMessageSettingsIconButton"));
const sizeCoverter_1 = require("../../utils/sizeCoverter");
const BaseDialog_1 = tslib_1.__importDefault(require("../../shared/BaseDialog"));
const Lightbox_1 = tslib_1.__importDefault(require("../../shared/Lightbox"));
const AutoPlayer_1 = tslib_1.__importDefault(require("../../shared/AutoPlayer"));
const notistack_1 = require("notistack");
const constants_1 = require("./constants");
const thumbnailCoverter_1 = require("../../utils/thumbnailCoverter");
const classes = {
root: `${constants_1.PREFIX}-root`,
username: `${constants_1.PREFIX}-username`,
text: `${constants_1.PREFIX}-text`,
img: `${constants_1.PREFIX}-img`,
document: `${constants_1.PREFIX}-document`,
video: `${constants_1.PREFIX}-video`,
other: `${constants_1.PREFIX}-other`,
iconButton: `${constants_1.PREFIX}-icon-button`,
messageTime: `${constants_1.PREFIX}-message-time`,
menuItem: `${constants_1.PREFIX}-menu-item`,
downloadButton: `${constants_1.PREFIX}-download-button`,
dialogRoot: `${constants_1.PREFIX}-dialog-root`
};
const DialogRoot = (0, styles_1.styled)(BaseDialog_1.default, {
name: constants_1.PREFIX,
slot: 'DialogRoot'
})(() => ({}));
const Root = (0, styles_1.styled)(material_1.ListItem, {
name: constants_1.PREFIX,
slot: 'Root'
})(() => ({}));
/**
* > API documentation for the Community-JS PrivateMessageItem component. Learn about the available props and the CSS API.
#### Import
```jsx
import {PrivateMessageThreadItem} from '@selfcommunity/react-ui';
```
#### Component Name
The name `SCPrivateMessageThreadItem` can be used when providing style overrides in the theme.
#### CSS
|Rule Name|Global class|Description|
|---|---|---|
|root|.SCPrivateMessageThreadItem-root|Styles applied to the root element.|
|text|.SCPrivateMessageThreadItem-text|Styles applied to the message text element.|
|img|.SCPrivateMessageThreadItem-img|Styles applied to the img element.|
|document|.SCPrivateMessageThreadItem-document|Styles applied to the message file element.|
|video|.SCPrivateMessageThreadItem-video|Styles applied to the message video element.|
|other|.SCPrivateMessageThreadItem-other|Styles applied to other media type element.|
|messageTime|.SCPrivateMessageThreadItem-message-time|Styles applied to the thread message time element.|
|menuItem|.SCPrivateMessageThreadItem-menu-item|Styles applied to the thread message menu item element.|
|dialogRoot|.SCPrivateMessageThreadItem-dialog-root|Styles applied to dialog root element.|
* @param inProps
*/
function PrivateMessageThreadItem(inProps) {
var _a;
// PROPS
const props = (0, system_1.useThemeProps)({
props: inProps,
name: constants_1.PREFIX
});
const { message = null, className = null, mouseEvents = {}, isHovering = null, showMenuIcon = false, onMenuIconClick = null } = props, rest = tslib_1.__rest(props, ["message", "className", "mouseEvents", "isHovering", "showMenuIcon", "onMenuIconClick"]);
// INTL
const intl = (0, react_intl_1.useIntl)();
// CONTEXT
const scUserContext = (0, react_1.useContext)(react_core_1.SCUserContext);
// STATE
const theme = (0, material_1.useTheme)();
const isMobile = (0, useMediaQuery_1.default)(theme.breakpoints.down('md'));
const hasFile = message ? message.file : null;
const [openDialog, setOpenDialog] = (0, react_1.useState)(false);
const { enqueueSnackbar } = (0, notistack_1.useSnackbar)();
const getMouseEvents = (mouseEnter, mouseLeave) => ({
onMouseEnter: mouseEnter,
onMouseLeave: mouseLeave,
onTouchStart: mouseEnter,
onTouchMove: mouseLeave
});
const handleMenuItemClick = () => {
onMenuIconClick();
};
const handleDownload = (file) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
const response = yield fetch(file.url);
const data = yield response.blob();
const blob = URL.createObjectURL(data);
const link = document.createElement('a');
link.href = blob;
link.download = file.filename;
link.click();
URL.revokeObjectURL(blob);
link.remove();
}
catch (error) {
console.log(error);
enqueueSnackbar(error, {
variant: 'error',
autoHideDuration: 3000
});
}
});
// RENDERING
const renderMessageFile = (m) => {
if (!m) {
return null;
}
let section = null;
const defaultSection = ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.other }, { children: (0, jsx_runtime_1.jsxs)(material_1.Button, Object.assign({ onClick: () => handleDownload(m.file), startIcon: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "download" }) }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { children: m.file.filename }), (0, jsx_runtime_1.jsx)(material_1.Typography, { children: (0, sizeCoverter_1.bytesToSize)(m.file.filesize) })] })) })));
if (m.file) {
let type = m.file.mimetype;
switch (true) {
case type.startsWith(types_1.SCMessageFileType.IMAGE):
section = ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.img }, { children: (0, jsx_runtime_1.jsx)("img", { src: m.file.thumbnail, loading: "lazy", alt: 'img', onClick: () => setOpenDialog(true) }) })));
break;
case type.startsWith(types_1.SCMessageFileType.VIDEO):
if (!(0, thumbnailCoverter_1.isSupportedVideoFormat)(m.file.filename)) {
section = defaultSection;
}
else {
section = ((0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: (0, classnames_1.default)(classes.img, classes.video) }, { children: [(0, jsx_runtime_1.jsx)("img", { src: m.file.thumbnail, loading: "lazy", alt: 'img' }), (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ onClick: () => setOpenDialog(true) }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "play_circle_outline" }) }))] })));
}
break;
case type.startsWith(types_1.SCMessageFileType.DOCUMENT):
section = ((0, jsx_runtime_1.jsxs)(material_1.Box, Object.assign({ className: m.file.filename.endsWith('.pdf') ? classes.document : classes.other }, { children: [m.file.filename.endsWith('.pdf') && (0, jsx_runtime_1.jsx)("img", { src: m.file.thumbnail, loading: "lazy", alt: 'img' }), (0, jsx_runtime_1.jsxs)(material_1.Button, Object.assign({ onClick: () => handleDownload(m.file), startIcon: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "download" }) }, { children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { children: m.file.filename }), (0, jsx_runtime_1.jsx)(material_1.Typography, { children: (0, sizeCoverter_1.bytesToSize)(m.file.filesize) })] }))] })));
break;
default:
// section = <Icon>hide_image</Icon>;
section = defaultSection;
break;
}
}
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: section });
};
if (!message) {
return (0, jsx_runtime_1.jsx)(Skeleton_1.default, { elevation: 0 });
}
/**
* Renders root object
*/
return ((0, jsx_runtime_1.jsxs)(Root, Object.assign({ className: (0, classnames_1.default)(classes.root, className) }, getMouseEvents(mouseEvents.onMouseEnter, mouseEvents.onMouseLeave), rest, { secondaryAction: (isHovering || isMobile) &&
showMenuIcon &&
message.status !== types_1.SCPrivateMessageStatusType.HIDDEN && (0, jsx_runtime_1.jsx)(PrivateMessageSettingsIconButton_1.default, { onMenuItemDeleteClick: handleMenuItemClick }) }, { children: [message.group && ((_a = scUserContext === null || scUserContext === void 0 ? void 0 : scUserContext.user) === null || _a === void 0 ? void 0 : _a.username) !== message.sender.username && ((0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ color: "secondary", variant: "h4", className: classes.username }, { children: message.sender.username }))), (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [hasFile && message.status !== types_1.SCPrivateMessageStatusType.HIDDEN ? (renderMessageFile(message)) : ((0, jsx_runtime_1.jsx)(material_1.Box, Object.assign({ className: classes.text }, { children: (0, jsx_runtime_1.jsx)(material_1.Typography, { component: "span", dangerouslySetInnerHTML: { __html: message.message } }) }))), (0, jsx_runtime_1.jsx)(material_1.Typography, Object.assign({ className: classes.messageTime, color: "text.secondary" }, { children: `${intl.formatDate(message.created_at, {
hour: 'numeric',
minute: 'numeric'
})}` }))] }), openDialog && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (message === null || message === void 0 ? void 0 : message.file.mimetype.startsWith(types_1.SCMessageFileType.VIDEO)) ? ((0, jsx_runtime_1.jsx)(DialogRoot, Object.assign({ open: openDialog, onClose: () => setOpenDialog(false), className: classes.dialogRoot }, { children: (0, jsx_runtime_1.jsx)(AutoPlayer_1.default, { url: message === null || message === void 0 ? void 0 : message.file.url, width: '100%', enableAutoplay: false }) }))) : ((0, jsx_runtime_1.jsx)(Lightbox_1.default, { images: [{ src: message === null || message === void 0 ? void 0 : message.file.url, key: message.file.uuid }], onClose: () => setOpenDialog(false), toolbarButtons: (0, jsx_runtime_1.jsx)(material_1.IconButton, Object.assign({ onClick: () => handleDownload(message === null || message === void 0 ? void 0 : message.file), className: classes.downloadButton }, { children: (0, jsx_runtime_1.jsx)(Icon_1.default, { children: "download" }) }), 'download') })) }))] })));
}
exports.default = PrivateMessageThreadItem;