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