mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-05-06 17:57:51 +00:00
Rename style file and add theme to chat
This commit is contained in:
parent
2013561db7
commit
69ff35b776
@ -1,28 +1,28 @@
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import DOMPurify from 'dompurify';
|
||||
import './styles.css';
|
||||
import './chat.css';
|
||||
import { executeEvent } from '../../utils/events';
|
||||
import { Embed } from '../Embeds/Embed';
|
||||
|
||||
export const extractComponents = (url) => {
|
||||
if (!url || !url.startsWith("qortal://")) {
|
||||
if (!url || !url.startsWith('qortal://')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Skip links starting with "qortal://use-"
|
||||
if (url.startsWith("qortal://use-")) {
|
||||
if (url.startsWith('qortal://use-')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
url = url.replace(/^(qortal\:\/\/)/, "");
|
||||
if (url.includes("/")) {
|
||||
let parts = url.split("/");
|
||||
url = url.replace(/^(qortal\:\/\/)/, '');
|
||||
if (url.includes('/')) {
|
||||
let parts = url.split('/');
|
||||
const service = parts[0].toUpperCase();
|
||||
parts.shift();
|
||||
const name = parts[0];
|
||||
parts.shift();
|
||||
let identifier;
|
||||
const path = parts.join("/");
|
||||
const path = parts.join('/');
|
||||
return { service, name, identifier, path };
|
||||
}
|
||||
|
||||
@ -64,8 +64,7 @@ function processText(input) {
|
||||
}
|
||||
|
||||
const linkify = (text) => {
|
||||
if (!text) return ""; // Return an empty string if text is null or undefined
|
||||
|
||||
if (!text) return ''; // Return an empty string if text is null or undefined
|
||||
let textFormatted = text;
|
||||
const urlPattern = /(\bhttps?:\/\/[^\s<]+|\bwww\.[^\s<]+)/g;
|
||||
textFormatted = text.replace(urlPattern, (url) => {
|
||||
@ -75,22 +74,66 @@ const linkify = (text) => {
|
||||
return processText(textFormatted);
|
||||
};
|
||||
|
||||
|
||||
export const MessageDisplay = ({ htmlContent, isReply }) => {
|
||||
|
||||
|
||||
const sanitizedContent = useMemo(()=> {
|
||||
const sanitizedContent = useMemo(() => {
|
||||
return DOMPurify.sanitize(linkify(htmlContent), {
|
||||
ALLOWED_TAGS: [
|
||||
'a', 'b', 'i', 'em', 'strong', 'p', 'br', 'div', 'span', 'img',
|
||||
'ul', 'ol', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote', 'code', 'pre', 'table', 'thead', 'tbody', 'tr', 'th', 'td', 's', 'hr'
|
||||
'a',
|
||||
'b',
|
||||
'i',
|
||||
'em',
|
||||
'strong',
|
||||
'p',
|
||||
'br',
|
||||
'div',
|
||||
'span',
|
||||
'img',
|
||||
'ul',
|
||||
'ol',
|
||||
'li',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'blockquote',
|
||||
'code',
|
||||
'pre',
|
||||
'table',
|
||||
'thead',
|
||||
'tbody',
|
||||
'tr',
|
||||
'th',
|
||||
'td',
|
||||
's',
|
||||
'hr',
|
||||
],
|
||||
ALLOWED_ATTR: [
|
||||
'href', 'target', 'rel', 'class', 'src', 'alt', 'title',
|
||||
'width', 'height', 'style', 'align', 'valign', 'colspan', 'rowspan', 'border', 'cellpadding', 'cellspacing', 'data-url'
|
||||
'href',
|
||||
'target',
|
||||
'rel',
|
||||
'class',
|
||||
'src',
|
||||
'alt',
|
||||
'title',
|
||||
'width',
|
||||
'height',
|
||||
'style',
|
||||
'align',
|
||||
'valign',
|
||||
'colspan',
|
||||
'rowspan',
|
||||
'border',
|
||||
'cellpadding',
|
||||
'cellspacing',
|
||||
'data-url',
|
||||
],
|
||||
}).replace(/<span[^>]*data-url="qortal:\/\/use-embed\/[^"]*"[^>]*>.*?<\/span>/g, '');
|
||||
}, [htmlContent])
|
||||
}).replace(
|
||||
/<span[^>]*data-url="qortal:\/\/use-embed\/[^"]*"[^>]*>.*?<\/span>/g,
|
||||
''
|
||||
);
|
||||
}, [htmlContent]);
|
||||
|
||||
const handleClick = async (e) => {
|
||||
e.preventDefault();
|
||||
@ -98,7 +141,7 @@ export const MessageDisplay = ({ htmlContent, isReply }) => {
|
||||
const target = e.target;
|
||||
if (target.tagName === 'A') {
|
||||
const href = target.getAttribute('href');
|
||||
if(window?.electronAPI){
|
||||
if (window?.electronAPI) {
|
||||
window.electronAPI.openExternal(href);
|
||||
} else {
|
||||
window.open(href, '_system');
|
||||
@ -106,32 +149,32 @@ export const MessageDisplay = ({ htmlContent, isReply }) => {
|
||||
} else if (target.getAttribute('data-url')) {
|
||||
const url = target.getAttribute('data-url');
|
||||
|
||||
let copyUrl = url
|
||||
let copyUrl = url;
|
||||
|
||||
try {
|
||||
copyUrl = copyUrl.replace(/^(qortal:\/\/)/, '')
|
||||
if (copyUrl.startsWith('use-')) {
|
||||
// Handle the new 'use' format
|
||||
const parts = copyUrl.split('/')
|
||||
const type = parts[0].split('-')[1] // e.g., 'group' from 'use-group'
|
||||
parts.shift()
|
||||
const action = parts.length > 0 ? parts[0].split('-')[1] : null // e.g., 'invite' from 'action-invite'
|
||||
parts.shift()
|
||||
const idPrefix = parts.length > 0 ? parts[0].split('-')[0] : null // e.g., 'groupid' from 'groupid-321'
|
||||
const id = parts.length > 0 ? parts[0].split('-')[1] : null // e.g., '321' from 'groupid-321'
|
||||
if(action === 'join'){
|
||||
executeEvent("globalActionJoinGroup", { groupId: id});
|
||||
return
|
||||
try {
|
||||
copyUrl = copyUrl.replace(/^(qortal:\/\/)/, '');
|
||||
if (copyUrl.startsWith('use-')) {
|
||||
// Handle the new 'use' format
|
||||
const parts = copyUrl.split('/');
|
||||
const type = parts[0].split('-')[1]; // e.g., 'group' from 'use-group'
|
||||
parts.shift();
|
||||
const action = parts.length > 0 ? parts[0].split('-')[1] : null; // e.g., 'invite' from 'action-invite'
|
||||
parts.shift();
|
||||
const idPrefix = parts.length > 0 ? parts[0].split('-')[0] : null; // e.g., 'groupid' from 'groupid-321'
|
||||
const id = parts.length > 0 ? parts[0].split('-')[1] : null; // e.g., '321' from 'groupid-321'
|
||||
if (action === 'join') {
|
||||
executeEvent('globalActionJoinGroup', { groupId: id });
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
//error
|
||||
}
|
||||
} catch (error) {
|
||||
//error
|
||||
}
|
||||
const res = extractComponents(url);
|
||||
if (res) {
|
||||
const { service, name, identifier, path } = res;
|
||||
executeEvent("addTab", { data: { service, name, identifier, path } });
|
||||
executeEvent("open-apps-mode", { });
|
||||
executeEvent('addTab', { data: { service, name, identifier, path } });
|
||||
executeEvent('open-apps-mode', {});
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -141,19 +184,17 @@ export const MessageDisplay = ({ htmlContent, isReply }) => {
|
||||
let embedData = null;
|
||||
|
||||
if (embedLink) {
|
||||
embedData = embedLink[0]
|
||||
embedData = embedLink[0];
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{embedLink && (
|
||||
<Embed embedLink={embedData} />
|
||||
)}
|
||||
<div
|
||||
className={`tiptap ${isReply ? 'isReply' : ''}`}
|
||||
dangerouslySetInnerHTML={{ __html: sanitizedContent }}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
{embedLink && <Embed embedLink={embedData} />}
|
||||
<div
|
||||
className={`tiptap ${isReply ? 'isReply' : ''}`}
|
||||
dangerouslySetInnerHTML={{ __html: sanitizedContent }}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
.tiptap {
|
||||
margin-top: 0;
|
||||
color: white; /* Set default font color to white */
|
||||
color: ''; /* Set default font color to white */
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@ -105,46 +105,45 @@
|
||||
color: white; /* Ensure paragraph text color is white */
|
||||
margin: 0px;
|
||||
}
|
||||
.tiptap p.is-editor-empty:first-child::before {
|
||||
color: #adb5bd;
|
||||
content: attr(data-placeholder);
|
||||
float: left;
|
||||
height: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.tiptap p.is-editor-empty:first-child::before {
|
||||
color: #adb5bd;
|
||||
content: attr(data-placeholder);
|
||||
float: left;
|
||||
height: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tiptap p:empty::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
}
|
||||
.tiptap p:empty::before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.tiptap a {
|
||||
color: cadetblue
|
||||
color: cadetblue;
|
||||
}
|
||||
|
||||
.tiptap img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.isReply p {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
||||
.tiptap [data-type="mention"] {
|
||||
.tiptap [data-type='mention'] {
|
||||
box-decoration-break: clone;
|
||||
color: lightblue;
|
||||
padding: 0.1rem 0.3rem;
|
||||
}
|
||||
|
||||
|
||||
.unread-divider {
|
||||
width: 90%;
|
||||
color: white;
|
||||
border-bottom: 1px solid white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
border-radius: 2px;
|
||||
color: white;
|
||||
border-bottom: 1px solid white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.mention-item {
|
||||
@ -176,4 +175,4 @@
|
||||
background-color: gray;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user