fix: Used Text component and snort transform instead of custom code

This commit is contained in:
florian 2023-12-19 15:03:56 +01:00
parent e973f31111
commit 2c751a813e
4 changed files with 25 additions and 92 deletions

View File

@ -1,73 +0,0 @@
import React from 'react';
interface RichTextContentProps {
text: string;
}
// Helper function to check if a string is an image URL
const isImageUrl = (string: string): boolean => /\.(jpeg|jpg|gif|png)$/.test(string);
// Helper function to check if a string is a web URL
const isWebUrl = (string: string): boolean => {
const urlPattern = 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
return !!urlPattern.test(string);
};
// Function to split the text into segments
const getSegments = (text: string): { type: 'text' | 'image' | 'link', content: string }[] => {
const words = text.match(/(\S+|\s+)/g) || [];
const segments: { type: 'text' | 'image' | 'link', content: string }[] = [];
let currentTextSegment = '';
words.forEach(word => {
const trimmedWord = word.trim();
if (isImageUrl(trimmedWord)) {
if (currentTextSegment) {
segments.push({ type: 'text', content: currentTextSegment });
currentTextSegment = '';
}
segments.push({ type: 'image', content: trimmedWord });
} else if (isWebUrl(trimmedWord)) {
if (currentTextSegment) {
segments.push({ type: 'text', content: currentTextSegment });
currentTextSegment = '';
}
segments.push({ type: 'link', content: trimmedWord });
} else {
currentTextSegment += word;
}
});
if (currentTextSegment) {
segments.push({ type: 'text', content: currentTextSegment });
}
return segments;
};
const RichTextContent: React.FC<RichTextContentProps> = ({ text }) => {
const segments = getSegments(text);
return (
<div>
{segments.map((segment, index) => {
switch(segment.type) {
case 'image':
return <img key={index} src={segment.content} style={{maxHeight:'50vh'}} />;
case 'link':
return <a key={index} href={segment.content} className="text-indigo-300" target="_blank" rel="noopener noreferrer">{segment.content}</a>;
default:
return <span key={index}>{segment.content}</span>;
}
})}
</div>
);
};
export default RichTextContent;

View File

@ -6,23 +6,25 @@ import { Link } from "react-router-dom";
export function Text({ content, tags }: { content: string; tags: Array<Array<string>> }) {
const frags = useMemo(() => transformText(content, tags), [content, tags]);
function renderFrag(f: ParsedFragment) {
function renderFrag(f: ParsedFragment, index: number) {
switch (f.type) {
case "media":
return <img key={index} src={f.content} style={{ maxHeight: "50vh" }} />;
case "mention":
case "link": {
const link = tryParseNostrLink(f.content);
if (link) {
return <Mention link={link} />;
const nostrLink = tryParseNostrLink(f.content);
if (nostrLink) {
return <Mention key={index} link={nostrLink} />;
} else {
return (
<Link to={f.content} target="_blank">
<Link key={index} to={f.content} target="_blank" className="text-indigo-300" rel="noopener noreferrer">
{f.content}
</Link>
);
}
}
default: {
return <span>{f.content}</span>;
return <span key={index}>{f.content}</span>;
}
}
}

View File

@ -10,7 +10,7 @@ export function TorrentList({ items }: { items: Array<TaggedNostrEvent> }) {
return (
<table className="torrent-list mb-8">
<thead>
<tr className="bg-neutral-800 h-8">
<tr className="h-8">
<th className="rounded-tl-lg">Category</th>
<th>Name</th>
<th>Uploaded</th>

View File

@ -9,7 +9,7 @@ import { useLogin } from "../login";
import { Button } from "../element/button";
import { Comments } from "../element/comments";
import { useMemo } from "react";
import RichTextContent from "../element/rich-text-content";
import { Text } from "../element/text";
export function TorrentPage() {
const location = useLocation();
@ -62,8 +62,8 @@ export function TorrentDetail({ item }: { item: TaggedNostrEvent }) {
<div className="flex items-center gap-2">
Tags:{" "}
<div className="flex gap-2">
{tags.map((a) => (
<div className="rounded-2xl py-1 px-4 bg-indigo-800 hover:bg-indigo-700">
{tags.map((a, i) => (
<div key={i} className="rounded-2xl py-1 px-4 bg-indigo-800 hover:bg-indigo-700">
<Link to={`/search/?tags=${a}`}>#{a}</Link>
</div>
))}
@ -89,7 +89,7 @@ export function TorrentDetail({ item }: { item: TaggedNostrEvent }) {
<>
<h3 className="mt-2">Description</h3>
<pre className="font-mono text-sm bg-neutral-900 p-4 rounded-lg overflow-y-auto">
<RichTextContent text={item.content}></RichTextContent>
<Text content={item.content} tags={item.tags}></Text>
</pre>
</>
)}
@ -97,19 +97,23 @@ export function TorrentDetail({ item }: { item: TaggedNostrEvent }) {
<div className="file-list flex flex-col gap-1 bg-neutral-900 p-4 rounded-lg">
<table className="w-max">
<thead>
<th>
<b>Filename</b>
</th>
<th>
<b>Size</b>
</th>
</thead>
{sortedFiles.map((a) => (
<tr>
<th>
<b>Filename</b>
</th>
<th>
<b>Size</b>
</th>
</tr>
</thead>
<tbody>
{sortedFiles.map((a, i) => (
<tr key={i}>
<td className="pr-4">{a[1]}</td>
<td className="text-neutral-500 font-semibold text-right text-sm">{FormatBytes(Number(a[2]))}</td>
</tr>
))}
</tbody>
</table>
</div>
<h3 className="mt-2">Comments</h3>