mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-04-19 19:01:19 +00:00
naddress slugs for all published details pages, also view nostr note buttons on all content
This commit is contained in:
parent
3b077b542a
commit
8b782ffc60
@ -1,22 +1,34 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
import ZapDisplay from "@/components/zaps/ZapDisplay";
|
||||
import { FileText } from "lucide-react"
|
||||
import Image from "next/image"
|
||||
import { useZapsSubscription } from "@/hooks/nostrQueries/zaps/useZapsSubscription";
|
||||
import { getTotalFromZaps } from "@/utils/lightning";
|
||||
import { useImageProxy } from "@/hooks/useImageProxy";
|
||||
import { useRouter } from "next/router";
|
||||
import { formatTimestampToHowLongAgo } from "@/utils/time";
|
||||
import { nip19 } from "nostr-tools";
|
||||
import { Tag } from "primereact/tag";
|
||||
import GenericButton from "@/components/buttons/GenericButton";
|
||||
|
||||
export function DocumentTemplate({ document }) {
|
||||
const { zaps, zapsLoading, zapsError } = useZapsSubscription({ event: document });
|
||||
const [nAddress, setNAddress] = useState(null);
|
||||
const [zapAmount, setZapAmount] = useState(0);
|
||||
const router = useRouter();
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
|
||||
useEffect(() => {
|
||||
if (document && document?.id) {
|
||||
const nAddress = nip19.naddrEncode({
|
||||
pubkey: document.pubkey,
|
||||
kind: document.kind,
|
||||
identifier: document.id,
|
||||
});
|
||||
setNAddress(nAddress);
|
||||
}
|
||||
}, [document]);
|
||||
|
||||
useEffect(() => {
|
||||
if (zaps.length > 0) {
|
||||
const total = getTotalFromZaps(zaps, document);
|
||||
@ -73,7 +85,7 @@ export function DocumentTemplate({ document }) {
|
||||
) : (
|
||||
formatTimestampToHowLongAgo(document.created_at)
|
||||
)}</p>
|
||||
<GenericButton onClick={() => router.push(`/details/${document.id}`)} size="small" label="Read" icon="pi pi-chevron-right" iconPos="right" outlined className="items-center py-2" />
|
||||
<GenericButton onClick={() => router.push(`/details/${nAddress}`)} size="small" label="Read" icon="pi pi-chevron-right" iconPos="right" outlined className="items-center py-2" />
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
|
@ -7,6 +7,7 @@ import { useZapsSubscription } from "@/hooks/nostrQueries/zaps/useZapsSubscripti
|
||||
import { getTotalFromZaps } from "@/utils/lightning";
|
||||
import { useImageProxy } from "@/hooks/useImageProxy";
|
||||
import { useRouter } from "next/router";
|
||||
import { nip19 } from "nostr-tools";
|
||||
import { formatTimestampToHowLongAgo } from "@/utils/time";
|
||||
import { Tag } from "primereact/tag";
|
||||
import GenericButton from "@/components/buttons/GenericButton";
|
||||
@ -14,9 +15,19 @@ import GenericButton from "@/components/buttons/GenericButton";
|
||||
export function VideoTemplate({ video }) {
|
||||
const { zaps, zapsLoading, zapsError } = useZapsSubscription({ event: video });
|
||||
const [zapAmount, setZapAmount] = useState(0);
|
||||
const [nAddress, setNAddress] = useState(null);
|
||||
const router = useRouter();
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
|
||||
useEffect(() => {
|
||||
const addr = nip19.naddrEncode({
|
||||
pubkey: video.pubkey,
|
||||
kind: video.kind,
|
||||
identifier: video.id
|
||||
})
|
||||
setNAddress(addr);
|
||||
}, [video]);
|
||||
|
||||
useEffect(() => {
|
||||
if (zaps.length > 0) {
|
||||
const total = getTotalFromZaps(zaps, video);
|
||||
@ -73,7 +84,7 @@ export function VideoTemplate({ video }) {
|
||||
) : (
|
||||
formatTimestampToHowLongAgo(video.created_at)
|
||||
)}</p>
|
||||
<GenericButton onClick={() => router.push(`/details/${video.id}`)} size="small" label="Watch" icon="pi pi-chevron-right" iconPos="right" outlined className="items-center py-2" />
|
||||
<GenericButton onClick={() => router.push(`/details/${nAddress}`)} size="small" label="Watch" icon="pi pi-chevron-right" iconPos="right" outlined className="items-center py-2" />
|
||||
</CardFooter>
|
||||
</Card>
|
||||
)
|
||||
|
@ -164,9 +164,7 @@ export default function CourseDetailsNew({ processedEvent, paidCourse, lessons,
|
||||
</div>
|
||||
)}
|
||||
{nAddress && (
|
||||
<div className='w-full flex flex-row justify-end'>
|
||||
<GenericButton outlined icon="pi pi-external-link" onClick={() => window.open(`https://nostr.band/${nAddress}`, '_blank')} tooltip="View Nostr Event" tooltipOptions={{ position: 'left' }} />
|
||||
</div>
|
||||
<GenericButton outlined icon="pi pi-external-link" onClick={() => window.open(`https://nostr.band/${nAddress}`, '_blank')} tooltip="View Nostr Event" tooltipOptions={{ position: paidCourse ? 'left' : 'right' }} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -86,7 +86,7 @@ const VideoLesson = ({ lesson, course, decryptionPerformed, isPaid }) => {
|
||||
<Divider />
|
||||
<div className="bg-gray-800/90 rounded-lg p-4 m-4">
|
||||
<div className="w-full flex flex-col items-start justify-start mt-2 px-2">
|
||||
<div className="flex flex-row items-center justify-between w-full">
|
||||
<div className="flex flex-row items-center gap-2 w-full">
|
||||
<h1 className='text-3xl text-white'>{lesson.title}</h1>
|
||||
{lesson.topics && lesson.topics.length > 0 && (
|
||||
lesson.topics.map((topic, index) => (
|
||||
|
@ -23,7 +23,7 @@ const MDDisplay = dynamic(
|
||||
|
||||
const lnAddress = process.env.NEXT_PUBLIC_LIGHTNING_ADDRESS;
|
||||
|
||||
const DocumentDetails = ({ processedEvent, topics, title, summary, image, price, author, paidResource, decryptedContent, handlePaymentSuccess, handlePaymentError, authorView }) => {
|
||||
const DocumentDetails = ({ processedEvent, topics, title, summary, image, price, author, paidResource, decryptedContent, nAddress, handlePaymentSuccess, handlePaymentError, authorView }) => {
|
||||
const [zapAmount, setZapAmount] = useState(0);
|
||||
const router = useRouter();
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
@ -151,6 +151,17 @@ const DocumentDetails = ({ processedEvent, topics, title, summary, image, price,
|
||||
zapsLoading={zapsLoading && zapAmount === 0}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full flex flex-row justify-end">
|
||||
<GenericButton
|
||||
tooltip={`View Nostr Note`}
|
||||
tooltipOptions={{ position: 'left' }}
|
||||
icon="pi pi-external-link"
|
||||
outlined
|
||||
onClick={() => {
|
||||
window.open(`https://nostr.com/${nAddress}`, '_blank');
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{renderContent()}
|
||||
|
@ -23,7 +23,7 @@ const MDDisplay = dynamic(
|
||||
|
||||
const lnAddress = process.env.NEXT_PUBLIC_LIGHTNING_ADDRESS;
|
||||
|
||||
const VideoDetails = ({ processedEvent, topics, title, summary, image, price, author, paidResource, decryptedContent, handlePaymentSuccess, handlePaymentError, authorView }) => {
|
||||
const VideoDetails = ({ processedEvent, topics, title, summary, image, price, author, paidResource, decryptedContent, nAddress, handlePaymentSuccess, handlePaymentError, authorView }) => {
|
||||
const [zapAmount, setZapAmount] = useState(0);
|
||||
const router = useRouter();
|
||||
const { returnImageProxy } = useImageProxy();
|
||||
@ -119,7 +119,7 @@ const VideoDetails = ({ processedEvent, topics, title, summary, image, price, au
|
||||
{renderContent()}
|
||||
<div className="bg-gray-800/90 rounded-lg p-4 m-4">
|
||||
<div className="w-full flex flex-col items-start justify-start mt-2 px-2">
|
||||
<div className="flex flex-row items-center justify-between w-full">
|
||||
<div className="flex flex-row items-center gap-2 w-full">
|
||||
<h1 className='text-4xl'>{title}</h1>
|
||||
{topics && topics.length > 0 && (
|
||||
topics.map((topic, index) => (
|
||||
@ -154,6 +154,15 @@ const VideoDetails = ({ processedEvent, topics, title, summary, image, price, au
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<GenericButton
|
||||
tooltip={`View Nostr Note`}
|
||||
tooltipOptions={{ position: 'left' }}
|
||||
icon="pi pi-external-link"
|
||||
outlined
|
||||
onClick={() => {
|
||||
window.open(`https://nostr.com/${nAddress}`, '_blank');
|
||||
}}
|
||||
/>
|
||||
{authorView && (
|
||||
<div className='flex flex-row justify-center items-center space-x-2'>
|
||||
<GenericButton onClick={() => router.push(`/details/${processedEvent.id}/edit`)} label="Edit" severity='warning' outlined />
|
||||
|
@ -40,7 +40,7 @@ const Sidebar = ({ course = false }) => {
|
||||
if (router.isReady) {
|
||||
const { slug } = router.query;
|
||||
|
||||
if (slug) {
|
||||
if (slug && course) {
|
||||
const { data } = nip19.decode(slug)
|
||||
|
||||
if (!data) {
|
||||
|
@ -68,14 +68,27 @@ export default function Details() {
|
||||
if (router.isReady) {
|
||||
const { slug } = router.query;
|
||||
|
||||
const fetchEvent = async (slug, retryCount = 0) => {
|
||||
if (!slug) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { data } = nip19.decode(slug)
|
||||
|
||||
if (!data) {
|
||||
showToast('error', 'Error', 'Resource not found');
|
||||
return;
|
||||
}
|
||||
|
||||
const id = data?.identifier;
|
||||
|
||||
const fetchEvent = async (id, retryCount = 0) => {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
await ndk.connect();
|
||||
|
||||
const filter = {
|
||||
ids: [slug]
|
||||
ids: [id]
|
||||
}
|
||||
|
||||
const event = await ndk.fetchEvent(filter);
|
||||
@ -93,7 +106,7 @@ export default function Details() {
|
||||
if (retryCount < 1) {
|
||||
// Wait for 2 seconds before retrying
|
||||
await new Promise(resolve => setTimeout(resolve, 3000));
|
||||
return fetchEvent(slug, retryCount + 1);
|
||||
return fetchEvent(id, retryCount + 1);
|
||||
} else {
|
||||
setError("Event not found");
|
||||
}
|
||||
@ -103,7 +116,7 @@ export default function Details() {
|
||||
if (retryCount < 1) {
|
||||
// Wait for 2 seconds before retrying
|
||||
await new Promise(resolve => setTimeout(resolve, 3000));
|
||||
return fetchEvent(slug, retryCount + 1);
|
||||
return fetchEvent(id, retryCount + 1);
|
||||
} else {
|
||||
setError("Failed to fetch event. Please try again.");
|
||||
}
|
||||
@ -112,8 +125,8 @@ export default function Details() {
|
||||
}
|
||||
};
|
||||
|
||||
if (ndk) {
|
||||
fetchEvent(slug);
|
||||
if (ndk && id) {
|
||||
fetchEvent(id);
|
||||
}
|
||||
}
|
||||
}, [router.isReady, router.query, ndk, user]);
|
||||
@ -200,6 +213,7 @@ export default function Details() {
|
||||
price={processedEvent.price}
|
||||
author={author}
|
||||
paidResource={paidResource}
|
||||
nAddress={nAddress}
|
||||
decryptedContent={decryptedContent}
|
||||
handlePaymentSuccess={handlePaymentSuccess}
|
||||
handlePaymentError={handlePaymentError}
|
||||
@ -216,13 +230,14 @@ export default function Details() {
|
||||
author={author}
|
||||
paidResource={paidResource}
|
||||
decryptedContent={decryptedContent}
|
||||
nAddress={nAddress}
|
||||
handlePaymentSuccess={handlePaymentSuccess}
|
||||
handlePaymentError={handlePaymentError}
|
||||
authorView={authorView}
|
||||
/>
|
||||
)}
|
||||
{typeof window !== 'undefined' && nAddress !== null && (
|
||||
<div className='max-tab:px-4'>
|
||||
<div className='px-4'>
|
||||
<ZapThreadsWrapper
|
||||
anchor={nAddress}
|
||||
user={user?.pubkey || null}
|
||||
|
Loading…
x
Reference in New Issue
Block a user