added images and video rendering in kind1's

This commit is contained in:
zmeyer44 2023-11-03 08:37:27 -04:00
parent 844263a983
commit 8b6778ae5e
8 changed files with 148 additions and 18 deletions

View File

@ -84,6 +84,25 @@ export default function EventPage({
/> />
</div> </div>
</div> </div>
<div className="flex flex-col pt-5 sm:gap-6">
<div className="flex items-center justify-between px-0">
<h2 className="font-condensed text-2xl font-bold">Past Events</h2>
</div>
<div className="mx-auto w-full max-w-[900px] space-y-6">
<EventsFromCalendar
calendar={event}
secondaryFilter={(e) =>
parseInt(getTagValues("start", e.tags) ?? "0") <
unixTimeNowInSeconds()
}
empty={() => (
<div className="py-3 text-center text-sm text-muted-foreground">
<p>No past events</p>
</div>
)}
/>
</div>
</div>
</div> </div>
); );
} }

View File

@ -49,3 +49,23 @@ export default function UserRow({ pubkey }: { pubkey: string }) {
</li> </li>
); );
} }
const raw = {
created_at: 1698235988,
content:
"Where's the kind 31923 Calendar event for nostr:npub1nstrcu63lzpjkz94djajuz2evrgu2psd66cwgc0gz0c0qazezx0q9urg5l?\n\nnote152vyaf30lj96mc6uyhgj54y6kdvf7y0s2zr5xva96ld338vfuqmsy829u7",
tags: [
[
"e",
"f4312118cac136538def1caf9b572fbc548b583701b952187f5c60ee49c3963c",
"",
"root",
],
["p", "9c163c7351f8832b08b56cbb2e095960d1c5060dd6b0e461e813f0f07459119e"],
["p", "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52"],
],
kind: 1,
pubkey: "17717ad4d20e2a425cda0a2195624a0a4a73c4f6975f16b1593fc87fa46f2d58",
id: "9b33153e60ad79dfb8b7801285963788583e21c3d0c4ca07054e18af7cbf5176",
sig: "55af918ad6bc3588bfbaff548c3199e628e606116a8b18d12caf2476a78ce2b65cbb8333aaf80ca350538ad6b6127cdb8ce67050c3ff9b1aa9ab3cf5f71a3581",
};

View File

@ -223,7 +223,7 @@ export default function CreateCalendarEventModal({
"invisible-input max-h-none !text-3xl font-bold text-foreground outline-none placeholder:text-muted-foreground/50 placeholder:hover:text-muted-foreground/80", "invisible-input max-h-none !text-3xl font-bold text-foreground outline-none placeholder:text-muted-foreground/50 placeholder:hover:text-muted-foreground/80",
title === "" && "max-h-[52px]", title === "" && "max-h-[52px]",
error["title"] && error["title"] &&
"border-b border-red-600 placeholder:text-red-600/50", "border-b border-destructive placeholder:text-red-600/50",
)} )}
/> />
<div className="mt-2 space-y-4"> <div className="mt-2 space-y-4">

View File

@ -14,20 +14,26 @@ import {
HiNewspaper, HiNewspaper,
HiCalendarDays, HiCalendarDays,
} from "react-icons/hi2"; } from "react-icons/hi2";
import { RiCalendarEventFill } from "react-icons/ri"; import { RiCalendarEventFill, RiEdit2Fill } from "react-icons/ri";
import { formatCount } from "@/lib/utils"; import { formatCount } from "@/lib/utils";
import LoginModal from "./Login";
import CreateList from "./CreateList";
import ShortTextNoteModal from "./ShortTextNote";
import CreateCalendarEventModal from "./CreateCalendarEvent"; import CreateCalendarEventModal from "./CreateCalendarEvent";
import CreateCalendarModal from "./CreateCalendar"; import CreateCalendarModal from "./CreateCalendar";
import Kind1Modal from "./Kind1";
import TileIconButton from "../Buttons/TileIconButton"; import TileIconButton from "../Buttons/TileIconButton";
export default function NewEventModal() { export default function NewEventModal() {
const modal = useModal(); const modal = useModal();
return ( return (
<Template title="Time to publish..." className="md:max-w-[400px]"> <Template title="Time to publish..." className="md:max-w-[400px]">
<div className="center gap-3 "> <div className="center items-stretch gap-3">
<TileIconButton
className="flex-1"
label="Add Note"
icon={(props) => <RiEdit2Fill {...props} />}
onClick={() => {
modal?.swap(<Kind1Modal />);
}}
/>
<TileIconButton <TileIconButton
className="flex-1" className="flex-1"
label="Add Event" label="Add Event"

View File

@ -0,0 +1,24 @@
import Image from "next/image";
import { cn } from "@/lib/utils";
export default function ImageUrl({
url,
className,
}: {
url: string;
className?: string;
}) {
return (
<div className={cn("relative overflow-hidden rounded-xl", className)}>
<Image
alt="Image"
height="288"
width="288"
unoptimized
src={url}
className={cn(
"h-full rounded-xl bg-background object-cover object-center max-sm:max-h-[100px]",
)}
/>
</div>
);
}

View File

@ -0,0 +1,24 @@
import ReactPlayer from "react-player";
import { cn } from "@/lib/utils";
export default function ImageUrl({
url,
className,
}: {
url: string;
className?: string;
}) {
return (
<div className={cn("relative overflow-hidden rounded-xl", className)}>
<ReactPlayer
url={url}
playing={true}
muted={false}
controls={true}
loop={true}
style={{
maxHeight: "300px",
}}
/>
</div>
);
}

View File

@ -1,7 +1,14 @@
import { cleanUrl } from "@/lib/utils"; import { cleanUrl, getFirstSubdomain } from "@/lib/utils";
import Link from "next/link"; import Link from "next/link";
import dynamic from "next/dynamic";
import ProfileMention from "./ProfileMention"; import ProfileMention from "./ProfileMention";
import EventMention from "./EventMention"; import EventMention from "./EventMention";
const ImageUrl = dynamic(() => import("./Image"), {
ssr: false,
});
const VideoUrl = dynamic(() => import("./Video"), {
ssr: false,
});
const urlRegex = const urlRegex =
/(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*))/g; /(https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*))/g;
@ -27,17 +34,37 @@ const RenderText = ({ text }: { text?: string }) => {
Elements.push(jsxElement); Elements.push(jsxElement);
let specialElement; let specialElement;
if (specialValuesArray?.length && specialValuesArray.length > index) { if (specialValuesArray?.length && specialValuesArray.length > index) {
if (specialValuesArray[index]?.match(urlRegex)) { const currentValue = specialValuesArray[index];
specialElement = ( if (currentValue?.match(urlRegex)) {
<a console.log("First zSub", getFirstSubdomain(currentValue));
className="text-primary hover:underline" const subdomain = getFirstSubdomain(currentValue);
href={cleanUrl(specialValuesArray[index])} if (!subdomain || subdomain === "www") {
target="_blank" specialElement = (
rel="noreferrer" <a
> className="text-primary hover:underline"
{cleanUrl(specialValuesArray[index])} href={cleanUrl(currentValue)}
</a> target="_blank"
); rel="noreferrer"
>
{cleanUrl(currentValue)}
</a>
);
} else if (subdomain === "i" || subdomain === "image") {
specialElement = <ImageUrl className="my-1" url={currentValue} />;
} else if (["v", "video"].includes(subdomain)) {
specialElement = <VideoUrl className="my-1" url={currentValue} />;
} else {
specialElement = (
<a
className="text-primary hover:underline"
href={cleanUrl(currentValue)}
target="_blank"
rel="noreferrer"
>
{cleanUrl(currentValue)}
</a>
);
}
// specialElement = <ContentRendering url={specialValuesArray[index]} />; // specialElement = <ContentRendering url={specialValuesArray[index]} />;
// specialElement = <span>{cleanUrl(specialValuesArray[index])}</span>; // specialElement = <span>{cleanUrl(specialValuesArray[index])}</span>;
} else if (specialValuesArray[index]?.match(hashtagRegex)) { } else if (specialValuesArray[index]?.match(hashtagRegex)) {

View File

@ -21,6 +21,16 @@ export function cleanUrl(url?: string) {
} }
return url; return url;
} }
export function getFirstSubdomain(url: string): string | null {
// Use a regular expression to extract the first subdomain
const subdomainMatch = url.match(/^(https?:\/\/)?([^.]+)\./i);
if (subdomainMatch && subdomainMatch[2]) {
return subdomainMatch[2];
}
return null;
}
export function truncateText(text: string, size?: number) { export function truncateText(text: string, size?: number) {
let length = size ?? 5; let length = size ?? 5;