Render text blocks

This commit is contained in:
Ken-Håvard Lieng 2020-06-30 13:24:23 +02:00
parent ca4db66308
commit 307573830a
15 changed files with 662 additions and 345 deletions

View file

@ -0,0 +1,72 @@
import React from 'react';
import stringToRGB from 'utils/color';
function nickStyle(nick, color) {
const style = {
fontWeight: 400
};
if (color) {
style.color = stringToRGB(nick);
}
return style;
}
function renderBlock(block, coloredNick, key) {
switch (block.type) {
case 'text':
return block.text;
case 'link':
return (
<a target="_blank" rel="noopener noreferrer" href={block.url} key={key}>
{block.text}
</a>
);
case 'format':
return (
<span style={block.style} key={key}>
{block.text}
</span>
);
case 'nick':
return (
<span
className="message-sender"
style={nickStyle(block.text, coloredNick)}
key={key}
>
{block.text}
</span>
);
case 'events':
return (
<span className="message-events-more" key={key}>
{block.text}
</span>
);
default:
return null;
}
}
const Text = ({ children, coloredNick }) => {
if (!children) {
return null;
}
if (children.length > 1) {
let key = 0;
return children.map(block => renderBlock(block, coloredNick, key++));
}
if (children.length === 1) {
return renderBlock(children[0], coloredNick);
}
return children;
};
export default Text;

View file

@ -2,6 +2,7 @@ import React, { memo, useState, useEffect, useRef } from 'react';
import Modal from 'react-modal';
import { useSelector, useDispatch } from 'react-redux';
import { FiUsers, FiX } from 'react-icons/fi';
import Text from 'components/Text';
import useModal from 'components/modals/useModal';
import Button from 'components/ui/Button';
import { join } from 'state/channels';
@ -33,7 +34,9 @@ const Channel = memo(({ network, name, topic, userCount, joined }) => {
</Button>
)}
</div>
<p className="modal-channel-topic">{linkify(topic)}</p>
<p className="modal-channel-topic">
<Text>{linkify(topic)}</Text>
</p>
</div>
);
});

View file

@ -2,6 +2,7 @@ import React from 'react';
import Modal from 'react-modal';
import { useSelector } from 'react-redux';
import { FiX } from 'react-icons/fi';
import Text from 'components/Text';
import Button from 'components/ui/Button';
import useModal from 'components/modals/useModal';
import { getSelectedChannel } from 'state/channels';
@ -18,7 +19,9 @@ const Topic = () => {
<h2>Topic in {channel}</h2>
<Button icon={FiX} className="modal-close" onClick={closeModal} />
</div>
<p className="modal-content">{linkify(topic)}</p>
<p className="modal-content">
<Text>{linkify(topic)}</Text>
</p>
</Modal>
);
};

View file

@ -1,5 +1,6 @@
import React, { memo } from 'react';
import classnames from 'classnames';
import Text from 'components/Text';
import stringToRGB from 'utils/color';
const Message = ({ message, coloredNick, onNickClick }) => {
@ -38,7 +39,10 @@ const Message = ({ message, coloredNick, onNickClick }) => {
{message.from}
</span>
)}
<span> {message.content}</span>
<span>
{' '}
<Text coloredNick={coloredNick}>{message.content}</Text>
</span>
</p>
);
};

View file

@ -1,4 +1,5 @@
import React, { memo } from 'react';
import Text from 'components/Text';
import { timestamp, linkify } from 'utils';
const SearchResult = ({ result }) => {
@ -16,7 +17,10 @@ const SearchResult = ({ result }) => {
{' '}
<span className="message-sender">{result.from}</span>
</span>
<span> {linkify(result.content)}</span>
<span>
{' '}
<Text>{linkify(result.content)}</Text>
</span>
</p>
);
};