mirror of
https://github.com/balzack/databag.git
synced 2025-02-14 20:49:16 +00:00
adding clickable links to webapp
This commit is contained in:
parent
46e76f7b76
commit
dc8c535793
@ -22,6 +22,7 @@
|
|||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"base-64": "^1.0.0",
|
"base-64": "^1.0.0",
|
||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
|
"dompurify": "^3.0.1",
|
||||||
"jsencrypt": "^2.3.1",
|
"jsencrypt": "^2.3.1",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-color": "^2.19.3",
|
"react-color": "^2.19.3",
|
||||||
|
@ -7,6 +7,7 @@ import { Space, Skeleton, Button, Modal, Input } from 'antd';
|
|||||||
import { ExclamationCircleOutlined, DeleteOutlined, EditOutlined, FireOutlined, PictureOutlined } from '@ant-design/icons';
|
import { ExclamationCircleOutlined, DeleteOutlined, EditOutlined, FireOutlined, PictureOutlined } from '@ant-design/icons';
|
||||||
import { Carousel } from 'carousel/Carousel';
|
import { Carousel } from 'carousel/Carousel';
|
||||||
import { useTopicItem } from './useTopicItem.hook';
|
import { useTopicItem } from './useTopicItem.hook';
|
||||||
|
import * as DOMPurify from 'dompurify';
|
||||||
|
|
||||||
export function TopicItem({ host, sealed, topic, update, remove }) {
|
export function TopicItem({ host, sealed, topic, update, remove }) {
|
||||||
|
|
||||||
@ -123,7 +124,7 @@ export function TopicItem({ host, sealed, topic, update, remove }) {
|
|||||||
)}
|
)}
|
||||||
{ !sealed && !state.editing && (
|
{ !sealed && !state.editing && (
|
||||||
<div class="message">
|
<div class="message">
|
||||||
<div style={{ color: topic.textColor, fontSize: topic.textSize }}>{ topic.text }</div>
|
<div style={{ color: topic.textColor, fontSize: topic.textSize }} dangerouslySetInnerHTML={{__html: DOMPurify.sanitize(topic.text, { ADD_ATTR: ['target'] })}} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{ state.editing && (
|
{ state.editing && (
|
||||||
|
@ -132,6 +132,27 @@ export function useConversation(cardId, channelId) {
|
|||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
}, [state.contentKey]);
|
}, [state.contentKey]);
|
||||||
|
|
||||||
|
const clickableText = (text) => {
|
||||||
|
var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
|
||||||
|
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
|
||||||
|
'((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
|
||||||
|
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
|
||||||
|
'(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
|
||||||
|
'(\\#[-a-z\\d_]*)?$','i'); // fragment locator
|
||||||
|
|
||||||
|
let clickable = '';
|
||||||
|
const words = text == null ? '' : text.split(' ');
|
||||||
|
words.forEach(word => {
|
||||||
|
if (!!pattern.test(word)) {
|
||||||
|
clickable += `<a target="_blank" rel="noopener noreferrer" href="${word}">${word}</a> `;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clickable += `${word} `;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return `<p>${clickable}</p>`;
|
||||||
|
};
|
||||||
|
|
||||||
const syncTopic = (item, value) => {
|
const syncTopic = (item, value) => {
|
||||||
const revision = value.data?.detailRevision;
|
const revision = value.data?.detailRevision;
|
||||||
const detail = value.data?.topicDetail || {};
|
const detail = value.data?.topicDetail || {};
|
||||||
@ -189,14 +210,14 @@ export function useConversation(cardId, channelId) {
|
|||||||
if (detail.dataType === 'superbasictopic') {
|
if (detail.dataType === 'superbasictopic') {
|
||||||
const message = JSON.parse(detail.data);
|
const message = JSON.parse(detail.data);
|
||||||
item.assets = message.assets;
|
item.assets = message.assets;
|
||||||
item.text = message.text;
|
item.text = clickableText(message.text);
|
||||||
item.textColor = message.textColor ? message.textColor : '#444444';
|
item.textColor = message.textColor ? message.textColor : '#444444';
|
||||||
item.textSize = message.textSize ? message.textSize : 14;
|
item.textSize = message.textSize ? message.textSize : 14;
|
||||||
}
|
}
|
||||||
if (detail.dataType === 'sealedtopic' && state.contentKey) {
|
if (detail.dataType === 'sealedtopic' && state.contentKey) {
|
||||||
const subject = decryptTopicSubject(detail.data, state.contentKey);
|
const subject = decryptTopicSubject(detail.data, state.contentKey);
|
||||||
item.assets = subject.message.assets;
|
item.assets = subject.message.assets;
|
||||||
item.text = subject.message.text;
|
item.text = clickableText(subject.message.text);
|
||||||
item.textColor = subject.message.textColor ? subject.message.textColor : '#444444';
|
item.textColor = subject.message.textColor ? subject.message.textColor : '#444444';
|
||||||
item.textSize = subject.message.textSize ? subject.message.textSize : 14;
|
item.textSize = subject.message.textSize ? subject.message.textSize : 14;
|
||||||
}
|
}
|
||||||
|
@ -4366,6 +4366,11 @@ domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
domelementtype "^2.2.0"
|
domelementtype "^2.2.0"
|
||||||
|
|
||||||
|
dompurify@^3.0.1:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.1.tgz#a0933f38931b3238934dd632043b727e53004289"
|
||||||
|
integrity sha512-60tsgvPKwItxZZdfLmamp0MTcecCta3avOhsLgPZ0qcWt96OasFfhkeIRbJ6br5i0fQawT1/RBGB5L58/Jpwuw==
|
||||||
|
|
||||||
domutils@^1.7.0:
|
domutils@^1.7.0:
|
||||||
version "1.7.0"
|
version "1.7.0"
|
||||||
resolved "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz"
|
resolved "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz"
|
||||||
|
Loading…
Reference in New Issue
Block a user