import React from 'react'; import moment from 'moment'; import markdown from 'simple-markdown'; import SimpleBar from 'simplebar-react'; import defaultRules from './rules'; import { Chip, Avatar, useTheme, Stack, Tooltip, Box, Icon, View, ToggleButton, useMediaQuery } from '../'; // import message import DashupUIChatEmbed from './Embed'; // let context let Embed = null; let DashupUIContext = null; // create dashup grid body const DashupUIChatMessage = (props = {}) => { // theme const theme = useTheme(); // is mobile const isMobile = useMediaQuery('(max-width:800px)'); // get embeds const getEmbeds = () => { // return embeds return (props.message?.embeds || []).filter((e) => e && e.data && e.type); }; // in thread const inThread = () => { // return in thread return props.message?.by?.id === props.prev?.by?.id || (!props.message?.by?.id && props.message?.by?.name === props.prev?.by?.name); }; // parse content const parseContent = (dashup, text = '') => { // state const state = { inline : true, inQuote : false }; // add rules defaultRules.tags = { order : markdown.defaultRules.strong.order, match : function (source) { return /^[@#]\[([^\]]+)\]\(([^\)]+)\)/.exec(source); }, parse : function (capture, parse, state) { // get capture const [replace, display, id] = capture; // return tag return { id, display, replace, trigger : replace[0], }; }, react : (node, output, state) => { // check dashup if (!dashup) return; // page const page = node.trigger === '#' ? dashup.page(node.id) : null; // let color let color = page?.get('color'); let parent = (page && (page?.get('parent') || 'root') !== 'root') ? dashup.page(page?.get('parent')) : null; // check page if (page) { // get parentmost color while (parent && !color) { // get new parent const newParent = ((parent.get('parent') || 'root') !== 'root') ? dashup.page(parent.get('parent')) : null; color = newParent?.get('color'); // set parent parent = newParent; } } // url const url = node.trigger === '#' ? `/app/${node.id}` : null; // return jsx return ( { page?.get('icon') ? ( ) : null } ) } onClick={ () => url && eden.router.go(url) } contentEditable={ false } /> ); }, }; defaultRules.codeBlock = { ...markdown.defaultRules.codeBlock, match : markdown.inlineRegex(/^```(([a-z0-9-]+?)\n+)?\n*([^]+?)\n*```/i), parse : function (capture, parse, state) { return { lang : (capture[2] || '').trim(), content : capture[3] || '', inQuote : state.inQuote || false }; }, react : (node, output, state) => { return ( ); } } // parser const parser = markdown.parserFor({ ...defaultRules, ...(props.rules || {}), }); // output const reactOutput = markdown.outputFor({ ...defaultRules, ...(props.rules || {}), }, 'react'); // return return reactOutput(parser(text || '', state), state); }; // button sx const buttonSx = { paddingLeft : 1, paddingRight : 1, }; // is mine const isMine = props.message?.by?.id === (typeof eden !== 'undefined' ? eden : {})?.user?.get('_id'); // render body const renderBody = (data) => { // check removed if (props.message.removed) return ; // return jsx return ( { !!(((data.page && data.dashup?.can(data.page, 'manage')) || data.dashup?.can('admin')) || isMine) && ( (props.onRemove || data.onRemove)(props.message) } selected color="error" sx={ buttonSx }> ) } { inThread() ? ( ) : ( ) } { !inThread() && ( { props.message.by.name } { moment(props.message.created_at).fromNow() } ) } { parseContent(data.dashup, props.message.parsed || props.message.message) } { !!getEmbeds().length && ( { getEmbeds().map((embed, i) => { // return jsx return ( ); }) } ) } ); } // return jsx return props.noChat ? renderBody(props) : ( { (data) => { // render body return renderBody(data); } } ); }; // export default page menu export default (ctx) => { // use context Embed = DashupUIChatEmbed(ctx); DashupUIContext = ctx; // return actual component return DashupUIChatMessage; };