media display

This commit is contained in:
smolgrrr 2023-12-02 21:28:57 +11:00
parent 3398c61700
commit 107b93bbd3
5 changed files with 56 additions and 46 deletions

View File

@ -149,7 +149,7 @@ const NewNoteCard = ({
<XCircleIcon className="h-10 w-10 absolute shadow z-100 text-blue-500" /> <XCircleIcon className="h-10 w-10 absolute shadow z-100 text-blue-500" />
</button> </button>
)} )}
{renderMedia(file)} {renderMedia([file])}
</div> </div>
<div className="h-14 flex items-center justify-between"> <div className="h-14 flex items-center justify-between">
<div className="inline-flex items-center gap-2 bg-neutral-800 px-1.5 py-1 rounded-lg"> <div className="inline-flex items-center gap-2 bg-neutral-800 px-1.5 py-1 rounded-lg">

View File

@ -27,7 +27,7 @@ const PostCard = ({
repliedTo, repliedTo,
type type
}: CardProps) => { }: CardProps) => {
const { file } = parseContent(event); const { files } = parseContent(event);
const icon = getIconFromHash(event.pubkey); const icon = getIconFromHash(event.pubkey);
const metadataParsed = metadata ? getMetadata(metadata) : null; const metadataParsed = metadata ? getMetadata(metadata) : null;
const navigate = useNavigate(); const navigate = useNavigate();
@ -44,7 +44,7 @@ const PostCard = ({
<div className={`flex flex-col break-words ${type !== "OP" ? 'hover:cursor-pointer' : ''}`} onClick={handleClick}> <div className={`flex flex-col break-words ${type !== "OP" ? 'hover:cursor-pointer' : ''}`} onClick={handleClick}>
<ContentPreview key={event.id} eventdata={event} /> <ContentPreview key={event.id} eventdata={event} />
</div> </div>
{renderMedia(file)} {renderMedia(files)}
{repliedTo && <div className="flex items-center mt-1" > {repliedTo && <div className="flex items-center mt-1" >
<span className="text-xs text-gray-500">Reply to: </span> <span className="text-xs text-gray-500">Reply to: </span>
{uniqBy(repliedTo, 'pubkey').map((event, index) => ( {uniqBy(repliedTo, 'pubkey').map((event, index) => (

View File

@ -16,7 +16,7 @@ const QuoteEmbed = ({
event: Event; event: Event;
metadata: Event | null; metadata: Event | null;
}) => { }) => {
const { file } = parseContent(event); const { files } = parseContent(event);
const icon = getIconFromHash(event.pubkey); const icon = getIconFromHash(event.pubkey);
let metadataParsed = null; let metadataParsed = null;
@ -30,7 +30,7 @@ const QuoteEmbed = ({
<div className="flex flex-col break-words"> <div className="flex flex-col break-words">
<ContentPreview key={event.id} eventdata={event} /> <ContentPreview key={event.id} eventdata={event} />
</div> </div>
{renderMedia(file)} {renderMedia(files)}
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
{metadataParsed ? {metadataParsed ?
<img <img

View File

@ -51,24 +51,32 @@ export default async function FileUpload(file: File): Promise<UploadResult> {
}; };
} }
export const renderMedia = (file: string) => { export const renderMedia = (files: string[]) => {
const gridTemplateColumns = files.length > 1 ? 'repeat(2, 1fr)' : 'repeat(1, 1fr)';
const gridTemplateRows = files.length > 2 ? 'repeat(2, 1fr)' : 'repeat(1, 1fr)';
return (
<div style={{ display: 'grid', gridTemplateColumns, gridTemplateRows, gap: '2px' }}>
{files.map((file, index) => {
if (file && (file.endsWith(".mp4") || file.endsWith(".webm"))) { if (file && (file.endsWith(".mp4") || file.endsWith(".webm"))) {
return ( return (
<video <video
key={index}
controls controls
muted muted
src={file + "#t=0.1"} src={file + "#t=0.1"}
preload="metadata" preload="metadata"
className="thumb mt-2 rounded-md w-full" className="thumb mt-1 rounded-md w-full"
> >
<source src={file} type="video/mp4" /> <source src={file} type="video/mp4" />
</video> </video>
); );
} else if (!file.includes("http")) { } else if (!file.includes("http")) {
return <></>; return null;
} else { } else {
return ( return (
<img <img
key={index}
alt="Invalid thread" alt="Invalid thread"
loading="lazy" loading="lazy"
className="thumb mt-2 rounded-md w-full" className="thumb mt-2 rounded-md w-full"
@ -76,6 +84,9 @@ export const renderMedia = (file: string) => {
/> />
); );
} }
})}
</div>
);
}; };
export async function attachFile(file_input: File | null): Promise<string> { export async function attachFile(file_input: File | null): Promise<string> {

View File

@ -1,22 +1,21 @@
import { Event } from 'nostr-tools' import { Event } from 'nostr-tools'
function extractMediaUrl(content: string){ function extractMediaUrls(content: string): string[] {
const regex = /(https?:\/\/\S+\.(?:jpg|png|jpeg|gif|mp4|webm|mov|webp))/i; const regex = /(https?:\/\/\S+\.(?:jpg|png|jpeg|gif|mp4|webm|mov|webp))/gi;
const match = content.match(regex); const matches = content.match(regex);
if (match) { return matches || [];
return match[0]; }
} else {
return '' ;
}
}
export function parseContent(event: Event) { export function parseContent(event: Event) {
const file = extractMediaUrl(event.content) as string; const files = extractMediaUrls(event.content);
const contentWithoutFile = event.content.replace(file, ''); let contentWithoutFiles = event.content;
files.forEach(file => {
contentWithoutFiles = contentWithoutFiles.replace(file, '');
});
return { return {
comment: contentWithoutFile.trim(), comment: contentWithoutFiles.trim(),
file files
}; };
} }