service worker fix and modal swap
This commit is contained in:
parent
ae64e536dc
commit
5a09b0be77
@ -18,7 +18,13 @@ export default function ProfilePage({
|
||||
};
|
||||
}) {
|
||||
const [activeTab, setActiveTab] = useState("feed");
|
||||
const pubkey = nip19.decode(npub).data.toString();
|
||||
console.log("calling with ", npub);
|
||||
const { type, data } = nip19.decode(npub);
|
||||
console.log("RES", data);
|
||||
if (type !== "npub") {
|
||||
throw new Error("Invalid list");
|
||||
}
|
||||
const pubkey = data.toString();
|
||||
const { profile } = useProfile(pubkey);
|
||||
|
||||
const demo = [
|
||||
|
15
app/(app)/(profile)/layout.tsx
Normal file
15
app/(app)/(profile)/layout.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import { redirect } from "next/navigation";
|
||||
import { nip19 } from "nostr-tools";
|
||||
|
||||
export default function Layout(props: {
|
||||
children: React.ReactNode;
|
||||
params: {
|
||||
npub?: string;
|
||||
};
|
||||
}) {
|
||||
const key = props.params.npub;
|
||||
if (key === "service-worker.js") {
|
||||
redirect("/");
|
||||
}
|
||||
return props.children;
|
||||
}
|
@ -19,10 +19,15 @@ import {
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from "@/components/ui/tooltip";
|
||||
import ZapPicker from "@/components/Modals/ZapPicker";
|
||||
import dynamic from "next/dynamic";
|
||||
import { useModal } from "@/app/_providers/modal/provider";
|
||||
import { IconType } from "react-icons";
|
||||
|
||||
const ZapPickerModal = dynamic(() => import("@/components/Modals/ZapPicker"), {
|
||||
ssr: false,
|
||||
});
|
||||
const NewEventModal = dynamic(() => import("@/components/Modals/NewEvent"), {
|
||||
ssr: false,
|
||||
});
|
||||
type NavigationLink = {
|
||||
type: "link";
|
||||
href: string;
|
||||
@ -71,7 +76,7 @@ export default function Sidebar() {
|
||||
active: false,
|
||||
},
|
||||
{
|
||||
onClick: () => modal?.show(<ZapPicker />),
|
||||
onClick: () => modal?.show(<ZapPickerModal />),
|
||||
name: "zap",
|
||||
label: "Zap Flockstr",
|
||||
icon: HiOutlineLightningBolt,
|
||||
@ -192,14 +197,14 @@ export default function Sidebar() {
|
||||
})}
|
||||
<div className="center py-2 xl:justify-start">
|
||||
<Button
|
||||
onClick={() => modal?.show(<ZapPicker />)}
|
||||
onClick={() => modal?.show(<NewEventModal />)}
|
||||
size={"icon"}
|
||||
className="xl:hidden"
|
||||
>
|
||||
<RiAddFill className="h-6 w-6" />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => modal?.show(<ZapPicker />)}
|
||||
onClick={() => modal?.show(<NewEventModal />)}
|
||||
size={"lg"}
|
||||
className="hidden xl:flex"
|
||||
>
|
||||
|
@ -72,7 +72,9 @@ export default function FeaturedLists() {
|
||||
</SectionHeader>
|
||||
<SectionContent className="sm:md-feed-cols relative flex flex-col gap-3">
|
||||
{processedEvents.map((e) => (
|
||||
<ListCard key={e.id} event={e} />
|
||||
<Link href={`/list/${e.encode()}`}>
|
||||
<ListCard key={e.id} event={e} />
|
||||
</Link>
|
||||
))}
|
||||
</SectionContent>
|
||||
</Section>
|
||||
|
165
app/(app)/list/[naddr]/page.tsx
Normal file
165
app/(app)/list/[naddr]/page.tsx
Normal file
@ -0,0 +1,165 @@
|
||||
"use client";
|
||||
import { useState } from "react";
|
||||
import Image from "next/image";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import SubscriptionCard from "@/components/SubscriptionCard";
|
||||
import { HiCheckBadge } from "react-icons/hi2";
|
||||
import Tabs from "@/components/Tabs";
|
||||
import useProfile from "@/lib/hooks/useProfile";
|
||||
import { getTwoLetters, truncateText } from "@/lib/utils";
|
||||
import { nip19 } from "nostr-tools";
|
||||
import useEvents from "@/lib/hooks/useEvents";
|
||||
import Spinner from "@/components/spinner";
|
||||
import { getTagValues } from "@/lib/nostr/utils";
|
||||
|
||||
const demo = [
|
||||
{
|
||||
id: "1",
|
||||
title: "BTC Radio",
|
||||
description:
|
||||
"BTC Radio is the best fuking show ever. you should sub to it. now",
|
||||
picture:
|
||||
"https://assets.whop.com/cdn-cgi/image/width=1080/https://assets.whop.com/images/images/51602.original.png?1693358530",
|
||||
tags: ["music", "crypto", "art"],
|
||||
},
|
||||
];
|
||||
|
||||
export default function ListPage({
|
||||
params: { naddr },
|
||||
}: {
|
||||
params: {
|
||||
naddr: string;
|
||||
};
|
||||
}) {
|
||||
const [activeTab, setActiveTab] = useState("feed");
|
||||
const { type, data } = nip19.decode(naddr);
|
||||
console.log("PASSED", naddr, data);
|
||||
if (type !== "naddr") {
|
||||
throw new Error("Invalid list");
|
||||
}
|
||||
const { identifier, kind, pubkey } = data;
|
||||
const { profile } = useProfile(pubkey);
|
||||
const { events } = useEvents({
|
||||
filter: {
|
||||
authors: [pubkey],
|
||||
kinds: [kind],
|
||||
["#d"]: [identifier],
|
||||
limit: 1,
|
||||
},
|
||||
});
|
||||
const event = events[0];
|
||||
|
||||
if (!event) {
|
||||
return (
|
||||
<div className="center ">
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
const title =
|
||||
getTagValues("title", event.tags) ??
|
||||
getTagValues("name", event.tags) ??
|
||||
"Untitled";
|
||||
const image =
|
||||
getTagValues("image", event.tags) ??
|
||||
getTagValues("picture", event.tags) ??
|
||||
getTagValues("benner", event.tags);
|
||||
|
||||
const description = getTagValues("description", event.tags);
|
||||
return (
|
||||
<div className="relative mx-auto max-w-5xl space-y-6">
|
||||
<div className="relative bg-muted @container">
|
||||
<div className="absolute top-0 h-[8rem] w-full" />
|
||||
<div className="mx-auto max-w-5xl p-0">
|
||||
<div className="m-0 @5xl:px-5 @5xl:pt-8">
|
||||
<div className="relative w-full overflow-hidden bg-gradient-to-b from-primary pb-[29%] @5xl:rounded-[20px]">
|
||||
{!!profile?.banner && (
|
||||
<Image
|
||||
className="absolute inset-0 h-full w-full object-cover align-middle"
|
||||
src={profile.banner}
|
||||
width={400}
|
||||
height={100}
|
||||
alt="banner"
|
||||
unoptimized
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative mx-auto mb-4 mt-[calc(-0.4375_*_4rem)] flex max-w-[800px] items-end justify-between gap-2 px-3 sm:mt-[calc(-0.4375_*_4.5rem)] sm:px-5 md:mt-[calc(-0.5625_*_5rem)] lg:mt-[calc(-0.5625_*_6rem)]">
|
||||
<div className="z-1 ml-[calc(-1_*_3px)] overflow-hidden rounded-[0.5rem] bg-background p-[3px] sm:ml-[calc(-1_*_4px)] sm:p-[4px] lg:ml-[calc(-1_*_6px)] lg:rounded-[1rem] lg:p-[6px]">
|
||||
{profile?.image ? (
|
||||
<Image
|
||||
src={profile.image}
|
||||
className="aspect-square w-[4rem] overflow-hidden rounded-[calc(0.5rem_-_3px)] object-cover object-center sm:w-[4.5rem] sm:rounded-[calc(0.5rem_-_4px)] md:w-[5rem] lg:w-[6rem] lg:rounded-[calc(1rem_-_6px)]"
|
||||
unoptimized
|
||||
alt="profile picture"
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
) : (
|
||||
<div className="center aspect-square w-[4rem] overflow-hidden rounded-[calc(0.5rem_-_3px)] bg-muted object-cover object-center text-primary @xl:text-2xl sm:w-[4.5rem] sm:rounded-[calc(0.5rem_-_4px)] md:w-[5rem] lg:w-[6rem] lg:rounded-[calc(1rem_-_6px)]"></div>
|
||||
)}
|
||||
</div>
|
||||
<Button size={"sm"} className="rounded-sm px-5 sm:hidden">
|
||||
Follow
|
||||
</Button>
|
||||
<Button className="rounded-sm px-5 max-sm:hidden">Follow</Button>
|
||||
</div>
|
||||
<div className="mx-auto max-w-[800px] space-y-1 px-4">
|
||||
<div className="flex items-center gap-x-1.5 lg:gap-x-2.5">
|
||||
<h2 className="text-xl font-semibold sm:text-2xl lg:text-3xl">
|
||||
{title}
|
||||
</h2>
|
||||
{!!profile?.nip05 && (
|
||||
<HiCheckBadge className="h-5 w-5 text-primary lg:h-7 lg:w-7" />
|
||||
)}
|
||||
</div>
|
||||
<div className="flex items-center text-xs text-muted-foreground/80 md:text-sm">
|
||||
{!!profile?.name && <p>{profile.name}</p>}
|
||||
{!!profile?.name && !!profile.nip05 && (
|
||||
<>
|
||||
<div className="inline-flex px-1">·</div>
|
||||
<p>{profile.nip05}</p>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="pt-1 md:pt-2">
|
||||
{!!description && (
|
||||
<p className="line-clamp-3 text-xs text-muted-foreground md:text-sm">
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx-auto max-w-[800px] space-y-6">
|
||||
<div className="flex max-w-2xl flex-col gap-5">
|
||||
{demo.map((e) => (
|
||||
<SubscriptionCard key={e.id} {...e} />
|
||||
))}
|
||||
</div>
|
||||
<div className="">
|
||||
<Tabs
|
||||
tabs={[
|
||||
{
|
||||
name: "feed",
|
||||
label: "Feed",
|
||||
},
|
||||
{
|
||||
name: "media",
|
||||
label: "Media",
|
||||
},
|
||||
{
|
||||
name: "subscriptions",
|
||||
label: "Subscriptions",
|
||||
},
|
||||
]}
|
||||
activeTab={activeTab}
|
||||
setActiveTab={(t) => setActiveTab(t.name)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -21,6 +21,7 @@ type ModalProps = ReactElement | Modals;
|
||||
|
||||
type ModalContextProps = {
|
||||
show: (content: ModalProps) => void;
|
||||
swap: (content: ModalProps) => void;
|
||||
hide: () => void;
|
||||
};
|
||||
|
||||
@ -40,6 +41,13 @@ export function ModalProvider({ children }: { children: ReactNode }) {
|
||||
setShowModal(true);
|
||||
};
|
||||
|
||||
const swap = (content: ModalProps) => {
|
||||
hide();
|
||||
setTimeout(() => {
|
||||
show(content);
|
||||
}, 300);
|
||||
};
|
||||
|
||||
const hide = () => {
|
||||
setShowModal(false);
|
||||
setTimeout(() => {
|
||||
@ -48,7 +56,7 @@ export function ModalProvider({ children }: { children: ReactNode }) {
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalContext.Provider value={{ show, hide }}>
|
||||
<ModalContext.Provider value={{ show, hide, swap }}>
|
||||
{children}
|
||||
{showModal && (
|
||||
<Modal showModal={showModal} setShowModal={setShowModal}>
|
||||
|
47
components/Modals/NewEvent.tsx
Normal file
47
components/Modals/NewEvent.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
"use client";
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import Link from "next/link";
|
||||
import Template from "./Template";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useModal } from "@/app/_providers/modal/provider";
|
||||
import { nip19 } from "nostr-tools";
|
||||
// import { useKeys } from "@/app/_providers/keysProvider";
|
||||
import { useNDK } from "@/app/_providers/ndk";
|
||||
import useCurrentUser from "@/lib/hooks/useCurrentUser";
|
||||
import {
|
||||
HiChatBubbleLeftEllipsis,
|
||||
HiBookmarkSquare,
|
||||
HiNewspaper,
|
||||
} from "react-icons/hi2";
|
||||
import { RiSubtractFill, RiAddFill } from "react-icons/ri";
|
||||
import { formatCount } from "@/lib/utils";
|
||||
import LoginModal from "./Login";
|
||||
|
||||
export default function NewEventModal() {
|
||||
const modal = useModal();
|
||||
return (
|
||||
<Template title="New Event" className="md:max-w-[400px]">
|
||||
<div className="flex flex-col gap-y-5">
|
||||
<Button
|
||||
onClick={() => {
|
||||
modal?.swap(<LoginModal />);
|
||||
}}
|
||||
className="w-full gap-x-1"
|
||||
>
|
||||
<span>Short Text</span>
|
||||
<HiChatBubbleLeftEllipsis className="h-4 w-4" />
|
||||
</Button>
|
||||
<Link href={`/article/new`}>
|
||||
<Button className="w-full gap-x-1">
|
||||
<span>Long Form</span>
|
||||
<HiNewspaper className="h-4 w-4" />
|
||||
</Button>
|
||||
</Link>
|
||||
<Button className="w-full gap-x-1">
|
||||
<span>Content List</span>
|
||||
<HiBookmarkSquare className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</Template>
|
||||
);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user