mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-06-23 16:05:24 +00:00
Fix feeds rendering, fixed some mobile styles
This commit is contained in:
parent
508bf29ac5
commit
41ae0d6112
@ -113,6 +113,35 @@ export default function CourseDetails({ processedEvent, paidCourse, lessons, dec
|
|||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const renderAdditionalLinks = () => {
|
||||||
|
if (processedEvent?.additionalLinks && processedEvent.additionalLinks.length > 0) {
|
||||||
|
return (
|
||||||
|
<div className="my-4">
|
||||||
|
<p>Additional Links:</p>
|
||||||
|
{processedEvent.additionalLinks.map((link, index) => (
|
||||||
|
<div key={index} className="mb-2">
|
||||||
|
<a
|
||||||
|
className="text-blue-500 hover:underline hover:text-blue-600 break-words"
|
||||||
|
href={link}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
style={{
|
||||||
|
wordBreak: 'break-word',
|
||||||
|
overflowWrap: 'break-word',
|
||||||
|
display: 'inline-block',
|
||||||
|
maxWidth: '100%'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{link}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
if (!processedEvent || !author) {
|
if (!processedEvent || !author) {
|
||||||
return <div className='w-full h-full flex items-center justify-center'><ProgressSpinner /></div>;
|
return <div className='w-full h-full flex items-center justify-center'><ProgressSpinner /></div>;
|
||||||
}
|
}
|
||||||
@ -183,9 +212,10 @@ export default function CourseDetails({ processedEvent, paidCourse, lessons, dec
|
|||||||
<GenericButton className='my-2' outlined icon="pi pi-external-link" onClick={() => window.open(`https://nostr.band/${nAddress}`, '_blank')} tooltip={isMobileView ? null : "View Nostr Event"} tooltipOptions={{ position: paidCourse ? 'left' : 'right' }} />
|
<GenericButton className='my-2' outlined icon="pi pi-external-link" onClick={() => window.open(`https://nostr.band/${nAddress}`, '_blank')} tooltip={isMobileView ? null : "View Nostr Event"} tooltipOptions={{ position: paidCourse ? 'left' : 'right' }} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{renderAdditionalLinks()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -151,12 +151,22 @@ const DocumentDetails = ({ processedEvent, topics, title, summary, image, price,
|
|||||||
<div className="my-4">
|
<div className="my-4">
|
||||||
<p>Additional Links:</p>
|
<p>Additional Links:</p>
|
||||||
{processedEvent.additionalLinks.map((link, index) => (
|
{processedEvent.additionalLinks.map((link, index) => (
|
||||||
<React.Fragment key={index}>
|
<div key={index} className="mb-2">
|
||||||
<a className="text-blue-500 hover:underline hover:text-blue-600" href={link} target="_blank" rel="noopener noreferrer">
|
<a
|
||||||
|
className="text-blue-500 hover:underline hover:text-blue-600 break-words"
|
||||||
|
href={link}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
style={{
|
||||||
|
wordBreak: 'break-word',
|
||||||
|
overflowWrap: 'break-word',
|
||||||
|
display: 'inline-block',
|
||||||
|
maxWidth: '100%'
|
||||||
|
}}
|
||||||
|
>
|
||||||
{link}
|
{link}
|
||||||
</a>
|
</a>
|
||||||
<br />
|
</div>
|
||||||
</React.Fragment>
|
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -126,6 +126,35 @@ const VideoDetails = ({ processedEvent, topics, title, summary, image, price, au
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const renderAdditionalLinks = () => {
|
||||||
|
if (processedEvent?.additionalLinks && processedEvent.additionalLinks.length > 0) {
|
||||||
|
return (
|
||||||
|
<div className="my-4">
|
||||||
|
<p>Additional Links:</p>
|
||||||
|
{processedEvent.additionalLinks.map((link, index) => (
|
||||||
|
<div key={index} className="mb-2">
|
||||||
|
<a
|
||||||
|
className="text-blue-500 hover:underline hover:text-blue-600 break-words"
|
||||||
|
href={link}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
style={{
|
||||||
|
wordBreak: 'break-word',
|
||||||
|
overflowWrap: 'break-word',
|
||||||
|
display: 'inline-block',
|
||||||
|
maxWidth: '100%'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{link}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
{renderContent()}
|
{renderContent()}
|
||||||
@ -154,19 +183,7 @@ const VideoDetails = ({ processedEvent, topics, title, summary, image, price, au
|
|||||||
{(summary)?.split('\n').map((line, index) => (
|
{(summary)?.split('\n').map((line, index) => (
|
||||||
<p key={index}>{line}</p>
|
<p key={index}>{line}</p>
|
||||||
))}
|
))}
|
||||||
{processedEvent?.additionalLinks && processedEvent?.additionalLinks.length > 0 && (
|
{renderAdditionalLinks()}
|
||||||
<div className="my-4">
|
|
||||||
<p>Additional Links:</p>
|
|
||||||
{processedEvent.additionalLinks.map((link, index) => (
|
|
||||||
<React.Fragment key={index}>
|
|
||||||
<a className="text-blue-500 hover:underline hover:text-blue-600" href={link} target="_blank" rel="noopener noreferrer">
|
|
||||||
{link}
|
|
||||||
</a>
|
|
||||||
<br />
|
|
||||||
</React.Fragment>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex items-center'>
|
<div className='flex items-center'>
|
||||||
|
@ -33,7 +33,7 @@ const DiscordFeed = ({ searchQuery }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-gray-900 h-full w-full min-bottom-bar:w-[86vw]">
|
<div className="h-full w-full min-bottom-bar:w-[86vw]">
|
||||||
<div className="mx-4">
|
<div className="mx-4">
|
||||||
{filteredData.length > 0 ? (
|
{filteredData.length > 0 ? (
|
||||||
filteredData.map(message => (
|
filteredData.map(message => (
|
||||||
|
@ -108,7 +108,7 @@ const GlobalFeed = ({searchQuery}) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-gray-900 h-full w-full min-bottom-bar:w-[86vw]">
|
<div className="h-full w-full min-bottom-bar:w-[86vw]">
|
||||||
<div className="mx-4 mt-4">
|
<div className="mx-4 mt-4">
|
||||||
{combinedFeed.length > 0 ? (
|
{combinedFeed.length > 0 ? (
|
||||||
combinedFeed.map(item => (
|
combinedFeed.map(item => (
|
||||||
|
@ -5,45 +5,36 @@ import { useSession } from 'next-auth/react';
|
|||||||
import { findKind0Fields } from '@/utils/nostr';
|
import { findKind0Fields } from '@/utils/nostr';
|
||||||
import NostrIcon from '../../../public/images/nostr.png';
|
import NostrIcon from '../../../public/images/nostr.png';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { useImageProxy } from '@/hooks/useImageProxy';
|
|
||||||
import useWindowWidth from '@/hooks/useWindowWidth';
|
import useWindowWidth from '@/hooks/useWindowWidth';
|
||||||
import { nip19 } from 'nostr-tools';
|
import { nip19 } from 'nostr-tools';
|
||||||
import { useCommunityNotes } from '@/hooks/nostr/useCommunityNotes';
|
import { useCommunityNotes } from '@/hooks/nostr/useCommunityNotes';
|
||||||
import CommunityMessage from '@/components/feeds/messages/CommunityMessage';
|
import CommunityMessage from '@/components/feeds/messages/CommunityMessage';
|
||||||
import ZapThreadsWrapper from '@/components/ZapThreadsWrapper';
|
|
||||||
|
|
||||||
const NostrFeed = ({ searchQuery }) => {
|
const NostrFeed = ({ searchQuery }) => {
|
||||||
const { communityNotes, isLoading, error } = useCommunityNotes();
|
const { communityNotes, isLoading, error } = useCommunityNotes();
|
||||||
const { ndk } = useNDKContext();
|
const { ndk } = useNDKContext();
|
||||||
const { returnImageProxy } = useImageProxy();
|
|
||||||
const { data: session } = useSession();
|
const { data: session } = useSession();
|
||||||
const [authorData, setAuthorData] = useState({});
|
const [authorData, setAuthorData] = useState({});
|
||||||
const [npub, setNpub] = useState(null);
|
|
||||||
|
|
||||||
const windowWidth = useWindowWidth();
|
const windowWidth = useWindowWidth();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchAuthors = async () => {
|
const fetchAuthors = async () => {
|
||||||
const authorDataMap = {};
|
|
||||||
for (const message of communityNotes) {
|
for (const message of communityNotes) {
|
||||||
if (!authorDataMap[message.pubkey]) {
|
if (!authorData[message.pubkey]) {
|
||||||
const author = await fetchAuthor(message.pubkey);
|
const author = await fetchAuthor(message.pubkey);
|
||||||
authorDataMap[message.pubkey] = author;
|
setAuthorData(prevData => ({
|
||||||
|
...prevData,
|
||||||
|
[message.pubkey]: author
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setAuthorData(authorDataMap);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (communityNotes && communityNotes.length > 0) {
|
if (communityNotes && communityNotes.length > 0) {
|
||||||
fetchAuthors();
|
fetchAuthors();
|
||||||
}
|
}
|
||||||
}, [communityNotes]);
|
}, [communityNotes, authorData]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (session?.user?.pubkey) {
|
|
||||||
setNpub(nip19.npubEncode(session.user.pubkey));
|
|
||||||
}
|
|
||||||
}, [session]);
|
|
||||||
|
|
||||||
const fetchAuthor = async (pubkey) => {
|
const fetchAuthor = async (pubkey) => {
|
||||||
try {
|
try {
|
||||||
@ -86,7 +77,7 @@ const NostrFeed = ({ searchQuery }) => {
|
|||||||
.sort((a, b) => b.created_at - a.created_at);
|
.sort((a, b) => b.created_at - a.created_at);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-gray-900 h-full w-full min-bottom-bar:w-[86vw]">
|
<div className="h-full w-full min-bottom-bar:w-[86vw]">
|
||||||
<div className="mx-4 mt-4">
|
<div className="mx-4 mt-4">
|
||||||
{filteredNotes.length > 0 ? (
|
{filteredNotes.length > 0 ? (
|
||||||
filteredNotes.map(message => (
|
filteredNotes.map(message => (
|
||||||
@ -95,7 +86,7 @@ const NostrFeed = ({ searchQuery }) => {
|
|||||||
message={{
|
message={{
|
||||||
id: message.id,
|
id: message.id,
|
||||||
author: authorData[message.pubkey]?.username || message.pubkey.substring(0, 12) + '...',
|
author: authorData[message.pubkey]?.username || message.pubkey.substring(0, 12) + '...',
|
||||||
avatar: authorData[message.pubkey]?.avatar ? returnImageProxy(authorData[message.pubkey]?.avatar) : null,
|
avatar: authorData[message.pubkey]?.avatar,
|
||||||
content: message.content,
|
content: message.content,
|
||||||
timestamp: message.created_at * 1000,
|
timestamp: message.created_at * 1000,
|
||||||
channel: "plebdevs"
|
channel: "plebdevs"
|
||||||
@ -115,4 +106,4 @@ const NostrFeed = ({ searchQuery }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NostrFeed;
|
export default NostrFeed;
|
||||||
|
@ -45,7 +45,7 @@ const StackerNewsFeed = ({ searchQuery }) => {
|
|||||||
.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
|
.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-gray-900 h-full w-full min-bottom-bar:w-[86vw]">
|
<div className="h-full w-full min-bottom-bar:w-[86vw]">
|
||||||
<div className="mx-4 mt-4">
|
<div className="mx-4 mt-4">
|
||||||
{filteredItems && filteredItems.length > 0 ? (
|
{filteredItems && filteredItems.length > 0 ? (
|
||||||
filteredItems.map(item => (
|
filteredItems.map(item => (
|
||||||
|
@ -149,13 +149,20 @@ const SubscribeModal = ({ user }) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Card title={subscriptionCardTitle} className="w-fit m-4 mx-auto">
|
<Card title={subscriptionCardTitle} className="w-fit m-4 mx-auto">
|
||||||
{subscribed && (
|
{subscribed && !user?.role?.nwc && (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Message className="w-fit" severity="success" text="Subscribed!" />
|
<Message className="w-fit" severity="success" text="Subscribed!" />
|
||||||
<p className="mt-4">Thank you for your support 🎉</p>
|
<p className="mt-4">Thank you for your support 🎉</p>
|
||||||
<p className="text-sm text-gray-400">Pay-as-you-go subscription will renew on {subscribedUntil.toLocaleDateString()}</p>
|
<p className="text-sm text-gray-400">Pay-as-you-go subscription will renew on {subscribedUntil.toLocaleDateString()}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{subscribed && user?.role?.nwc && (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<Message className="w-fit" severity="success" text="Subscribed!" />
|
||||||
|
<p className="mt-4">Thank you for your support 🎉</p>
|
||||||
|
<p className="text-sm text-gray-400">Recurring subscription will AUTO renew on {subscribedUntil.toLocaleDateString()}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{(!subscribed && !subscriptionExpiredAt) && (
|
{(!subscribed && !subscriptionExpiredAt) && (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Message className="w-fit" severity="info" text="You currently have no active subscription" />
|
<Message className="w-fit" severity="info" text="You currently have no active subscription" />
|
||||||
|
@ -101,11 +101,18 @@ const UserSubscription = () => {
|
|||||||
<h1 className="text-3xl font-bold mb-6">Subscription Management</h1>
|
<h1 className="text-3xl font-bold mb-6">Subscription Management</h1>
|
||||||
)}
|
)}
|
||||||
<div className="mb-4 p-4 bg-gray-800 rounded-lg w-fit">
|
<div className="mb-4 p-4 bg-gray-800 rounded-lg w-fit">
|
||||||
{subscribed && (
|
{subscribed && !user?.role?.nwc && (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Message className="w-fit" severity="success" text="Subscribed!" />
|
<Message className="w-fit" severity="success" text="Subscribed!" />
|
||||||
<p className="mt-4">Thank you for your support 🎉</p>
|
<p className="mt-4">Thank you for your support 🎉</p>
|
||||||
<p className="text-sm text-gray-400">Pay-as-you-go subscription will renew on {subscribedUntil.toLocaleDateString()}</p>
|
<p className="text-sm text-gray-400">Pay-as-you-go subscription requires manual renewal on {subscribedUntil.toLocaleDateString()}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{subscribed && user?.role?.nwc && (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<Message className="w-fit" severity="success" text="Subscribed!" />
|
||||||
|
<p className="mt-4">Thank you for your support 🎉</p>
|
||||||
|
<p className="text-sm text-gray-400">Recurring subscription will AUTO renew on {subscribedUntil.toLocaleDateString()}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{(!subscribed && !subscriptionExpiredAt) && (
|
{(!subscribed && !subscriptionExpiredAt) && (
|
||||||
|
@ -11,7 +11,7 @@ const appConfig = {
|
|||||||
// "wss://purplerelay.com/",
|
// "wss://purplerelay.com/",
|
||||||
"wss://relay.devs.tools/"
|
"wss://relay.devs.tools/"
|
||||||
],
|
],
|
||||||
authorPubkeys: ["8cb60e215678879cda0bef4d5b3fc1a5c5925d2adb5d8c4fa7b7d03b5f2deaea", "676c02247668d5b18479be3d1a80933044256f3fbd03640a8c234684e641b6d6", "f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741", "c67cd3e1a83daa56cff16f635db2fdb9ed9619300298d4701a58e68e84098345"],
|
authorPubkeys: ["468f729dd409053dac5e7470622c3996aad88db6ed1de9165cb1921b5ab4fd5e","8cb60e215678879cda0bef4d5b3fc1a5c5925d2adb5d8c4fa7b7d03b5f2deaea", "676c02247668d5b18479be3d1a80933044256f3fbd03640a8c234684e641b6d6", "f33c8a9617cb15f705fc70cd461cfd6eaf22f9e24c33eabad981648e5ec6f741", "c67cd3e1a83daa56cff16f635db2fdb9ed9619300298d4701a58e68e84098345"],
|
||||||
customLightningAddresses: [
|
customLightningAddresses: [
|
||||||
{
|
{
|
||||||
// todo remove need for lowercase
|
// todo remove need for lowercase
|
||||||
|
@ -13,6 +13,7 @@ const AboutPage = () => {
|
|||||||
const windowWidth = useWindowWidth();
|
const windowWidth = useWindowWidth();
|
||||||
|
|
||||||
const isTabView = windowWidth <= 1360;
|
const isTabView = windowWidth <= 1360;
|
||||||
|
const isMobile = windowWidth < 768;
|
||||||
|
|
||||||
const copyToClipboard = async (text) => {
|
const copyToClipboard = async (text) => {
|
||||||
try {
|
try {
|
||||||
@ -31,9 +32,9 @@ const AboutPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`${isTabView ? 'w-full' : 'w-[83vw]'} p-4 mx-auto`}>
|
<div className={`${isTabView ? 'w-full' : 'w-[83vw]'} ${isMobile ? 'p-0' : 'p-4'} mx-auto`}>
|
||||||
<InteractivePromotionalCarousel />
|
<InteractivePromotionalCarousel />
|
||||||
<Card title="Key Features" className="mb-4">
|
<Card title="Key Features" className={`mb-4 ${isMobile ? 'm-2' : null}`}>
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
<div className="flex flex-col items-start justify-center">
|
<div className="flex flex-col items-start justify-center">
|
||||||
<div className='flex items-start'>
|
<div className='flex items-start'>
|
||||||
|
@ -51,7 +51,7 @@ const Feed = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-gray-900 h-[100vh] w-[100vw] min-bottom-bar:w-[86vw]">
|
<div className="h-[100vh] w-[100vw] min-bottom-bar:w-[86vw]">
|
||||||
<div className="w-[100vw] min-bottom-bar:w-[86vw] px-4 pt-4 flex flex-col items-start">
|
<div className="w-[100vw] min-bottom-bar:w-[86vw] px-4 pt-4 flex flex-col items-start">
|
||||||
<div className='mb-4 flex flex-row items-end'>
|
<div className='mb-4 flex flex-row items-end'>
|
||||||
<h1 className="font-bold mb-0">Feeds</h1>
|
<h1 className="font-bold mb-0">Feeds</h1>
|
||||||
|
@ -147,13 +147,20 @@ const Subscribe = () => {
|
|||||||
<div className="mb-4 p-4 bg-gray-800 rounded-lg w-fit">
|
<div className="mb-4 p-4 bg-gray-800 rounded-lg w-fit">
|
||||||
{session && session?.user ? (
|
{session && session?.user ? (
|
||||||
<>
|
<>
|
||||||
{subscribed && (
|
{subscribed && !user?.role?.nwc && (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Message className="w-fit" severity="success" text="Subscribed!" />
|
<Message className="w-fit" severity="success" text="Subscribed!" />
|
||||||
<p className="mt-4">Thank you for your support 🎉</p>
|
<p className="mt-4">Thank you for your support 🎉</p>
|
||||||
<p className="text-sm text-gray-400">Pay-as-you-go subscription must be manually renewed on {subscribedUntil.toLocaleDateString()}</p>
|
<p className="text-sm text-gray-400">Pay-as-you-go subscription must be manually renewed on {subscribedUntil.toLocaleDateString()}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{subscribed && user?.role?.nwc && (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<Message className="w-fit" severity="success" text="Subscribed!" />
|
||||||
|
<p className="mt-4">Thank you for your support 🎉</p>
|
||||||
|
<p className="text-sm text-gray-400">Recurring subscription will AUTO renew on {subscribedUntil.toLocaleDateString()}</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{(!subscribed && !subscriptionExpiredAt) && (
|
{(!subscribed && !subscriptionExpiredAt) && (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<Message className="w-fit" severity="info" text="You currently have no active subscription" />
|
<Message className="w-fit" severity="info" text="You currently have no active subscription" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user