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