added images and video rendering in kind1's
This commit is contained in:
parent
844263a983
commit
8b6778ae5e
@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
};
|
||||||
|
@ -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">
|
||||||
|
@ -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"
|
||||||
|
24
components/TextRendering/Image.tsx
Normal file
24
components/TextRendering/Image.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
24
components/TextRendering/Video.tsx
Normal file
24
components/TextRendering/Video.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
@ -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)) {
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user