mirror of
https://github.com/AustinKelsay/plebdevs.git
synced 2025-06-05 00:32:03 +00:00
Replaced all markdown displays with react-markdown and gituhb-markdown-css styles
This commit is contained in:
parent
0279140011
commit
d3bf9cc045
43
package-lock.json
generated
43
package-lock.json
generated
@ -35,6 +35,7 @@
|
|||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"discord.js": "^14.15.3",
|
"discord.js": "^14.15.3",
|
||||||
|
"github-markdown-css": "^5.8.1",
|
||||||
"light-bolt11-decoder": "^3.1.1",
|
"light-bolt11-decoder": "^3.1.1",
|
||||||
"lucide-react": "^0.441.0",
|
"lucide-react": "^0.441.0",
|
||||||
"next": "^14.2.28",
|
"next": "^14.2.28",
|
||||||
@ -48,6 +49,7 @@
|
|||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"reactflow": "^11.11.4",
|
"reactflow": "^11.11.4",
|
||||||
|
"remark-breaks": "^4.0.0",
|
||||||
"tailwind-merge": "^2.5.2",
|
"tailwind-merge": "^2.5.2",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"uuid": "^10.0.0",
|
"uuid": "^10.0.0",
|
||||||
@ -8651,6 +8653,18 @@
|
|||||||
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/github-markdown-css": {
|
||||||
|
"version": "5.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/github-markdown-css/-/github-markdown-css-5.8.1.tgz",
|
||||||
|
"integrity": "sha512-8G+PFvqigBQSWLQjyzgpa2ThD9bo7+kDsriUIidGcRhXgmcaAWUIpCZf8DavJgc+xifjbCG+GvMyWr0XMXmc7g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/github-slugger": {
|
"node_modules/github-slugger": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
|
||||||
@ -10920,6 +10934,20 @@
|
|||||||
"url": "https://opencollective.com/unified"
|
"url": "https://opencollective.com/unified"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/mdast-util-newline-to-break": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mdast-util-newline-to-break/-/mdast-util-newline-to-break-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-MbgeFca0hLYIEx/2zGsszCSEJJ1JSCdiY5xQxRcLDDGa8EPvlLPupJ4DSajbMPAnC0je8jfb9TiUATnxxrHUog==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/mdast": "^4.0.0",
|
||||||
|
"mdast-util-find-and-replace": "^3.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/unified"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/mdast-util-phrasing": {
|
"node_modules/mdast-util-phrasing": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz",
|
||||||
@ -13408,6 +13436,21 @@
|
|||||||
"url": "https://opencollective.com/unified"
|
"url": "https://opencollective.com/unified"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/remark-breaks": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/remark-breaks/-/remark-breaks-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-IjEjJOkH4FuJvHZVIW0QCDWxcG96kCq7An/KVH2NfJe6rKZU2AsHeB3OEjPNRxi4QC34Xdx7I2KGYn6IpT7gxQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/mdast": "^4.0.0",
|
||||||
|
"mdast-util-newline-to-break": "^2.0.0",
|
||||||
|
"unified": "^11.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/unified"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/remark-gfm": {
|
"node_modules/remark-gfm": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz",
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"discord.js": "^14.15.3",
|
"discord.js": "^14.15.3",
|
||||||
|
"github-markdown-css": "^5.8.1",
|
||||||
"light-bolt11-decoder": "^3.1.1",
|
"light-bolt11-decoder": "^3.1.1",
|
||||||
"lucide-react": "^0.441.0",
|
"lucide-react": "^0.441.0",
|
||||||
"next": "^14.2.28",
|
"next": "^14.2.28",
|
||||||
@ -51,6 +52,7 @@
|
|||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"reactflow": "^11.11.4",
|
"reactflow": "^11.11.4",
|
||||||
|
"remark-breaks": "^4.0.0",
|
||||||
"tailwind-merge": "^2.5.2",
|
"tailwind-merge": "^2.5.2",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"uuid": "^10.0.0",
|
"uuid": "^10.0.0",
|
||||||
|
@ -12,16 +12,12 @@ import { useZapsSubscription } from '@/hooks/nostrQueries/zaps/useZapsSubscripti
|
|||||||
import { getTotalFromZaps } from '@/utils/lightning';
|
import { getTotalFromZaps } from '@/utils/lightning';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
import useWindowWidth from '@/hooks/useWindowWidth';
|
import useWindowWidth from '@/hooks/useWindowWidth';
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import { Toast } from 'primereact/toast';
|
import { Toast } from 'primereact/toast';
|
||||||
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
||||||
import ZapThreadsWrapper from '@/components/ZapThreadsWrapper';
|
import ZapThreadsWrapper from '@/components/ZapThreadsWrapper';
|
||||||
import appConfig from '@/config/appConfig';
|
import appConfig from '@/config/appConfig';
|
||||||
import { nip19 } from 'nostr-tools';
|
import { nip19 } from 'nostr-tools';
|
||||||
|
import MarkdownDisplay from '@/components/markdown/MarkdownDisplay';
|
||||||
const MDDisplay = dynamic(() => import('@uiw/react-markdown-preview'), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const CombinedDetails = ({
|
const CombinedDetails = ({
|
||||||
processedEvent,
|
processedEvent,
|
||||||
@ -228,7 +224,7 @@ const CombinedDetails = ({
|
|||||||
|
|
||||||
const renderContent = () => {
|
const renderContent = () => {
|
||||||
if (decryptedContent) {
|
if (decryptedContent) {
|
||||||
return <MDDisplay className="p-2 rounded-lg w-full" source={decryptedContent} />;
|
return <MarkdownDisplay content={decryptedContent} className="p-2 rounded-lg w-full" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paidResource && !decryptedContent) {
|
if (paidResource && !decryptedContent) {
|
||||||
@ -256,7 +252,7 @@ const CombinedDetails = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (processedEvent?.content) {
|
if (processedEvent?.content) {
|
||||||
return <MDDisplay className="p-4 rounded-lg w-full" source={processedEvent.content} />;
|
return <MarkdownDisplay content={processedEvent.content} className="p-4 rounded-lg w-full" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -7,7 +7,6 @@ import { useZapsQuery } from '@/hooks/nostrQueries/zaps/useZapsQuery';
|
|||||||
import { nip19 } from 'nostr-tools';
|
import { nip19 } from 'nostr-tools';
|
||||||
import { Divider } from 'primereact/divider';
|
import { Divider } from 'primereact/divider';
|
||||||
import { getTotalFromZaps } from '@/utils/lightning';
|
import { getTotalFromZaps } from '@/utils/lightning';
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import useWindowWidth from '@/hooks/useWindowWidth';
|
import useWindowWidth from '@/hooks/useWindowWidth';
|
||||||
import appConfig from '@/config/appConfig';
|
import appConfig from '@/config/appConfig';
|
||||||
import useTrackVideoLesson from '@/hooks/tracking/useTrackVideoLesson';
|
import useTrackVideoLesson from '@/hooks/tracking/useTrackVideoLesson';
|
||||||
@ -15,10 +14,7 @@ import { Menu } from 'primereact/menu';
|
|||||||
import { Toast } from 'primereact/toast';
|
import { Toast } from 'primereact/toast';
|
||||||
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
|
import MarkdownDisplay from '@/components/markdown/MarkdownDisplay';
|
||||||
const MDDisplay = dynamic(() => import('@uiw/react-markdown-preview'), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const CombinedLesson = ({ lesson, course, decryptionPerformed, isPaid, setCompleted }) => {
|
const CombinedLesson = ({ lesson, course, decryptionPerformed, isPaid, setCompleted }) => {
|
||||||
const [zapAmount, setZapAmount] = useState(0);
|
const [zapAmount, setZapAmount] = useState(0);
|
||||||
@ -175,7 +171,7 @@ const CombinedLesson = ({ lesson, course, decryptionPerformed, isPaid, setComple
|
|||||||
if (isPaid && decryptionPerformed) {
|
if (isPaid && decryptionPerformed) {
|
||||||
return (
|
return (
|
||||||
<div ref={mdDisplayRef}>
|
<div ref={mdDisplayRef}>
|
||||||
<MDDisplay className={'p-4 rounded-lg w-full'} source={lesson.content} />
|
<MarkdownDisplay content={lesson.content} className="p-4 rounded-lg w-full" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -217,7 +213,7 @@ const CombinedLesson = ({ lesson, course, decryptionPerformed, isPaid, setComple
|
|||||||
if (lesson?.content) {
|
if (lesson?.content) {
|
||||||
return (
|
return (
|
||||||
<div ref={mdDisplayRef}>
|
<div ref={mdDisplayRef}>
|
||||||
<MDDisplay className={'p-4 rounded-lg w-full'} source={lesson.content} />
|
<MarkdownDisplay content={lesson.content} className="p-4 rounded-lg w-full" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import Image from 'next/image';
|
|||||||
import { useImageProxy } from '@/hooks/useImageProxy';
|
import { useImageProxy } from '@/hooks/useImageProxy';
|
||||||
import { getTotalFromZaps } from '@/utils/lightning';
|
import { getTotalFromZaps } from '@/utils/lightning';
|
||||||
import ZapDisplay from '@/components/zaps/ZapDisplay';
|
import ZapDisplay from '@/components/zaps/ZapDisplay';
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import { useZapsQuery } from '@/hooks/nostrQueries/zaps/useZapsQuery';
|
import { useZapsQuery } from '@/hooks/nostrQueries/zaps/useZapsQuery';
|
||||||
import { Toast } from 'primereact/toast';
|
import { Toast } from 'primereact/toast';
|
||||||
import useTrackDocumentLesson from '@/hooks/tracking/useTrackDocumentLesson';
|
import useTrackDocumentLesson from '@/hooks/tracking/useTrackDocumentLesson';
|
||||||
@ -13,10 +12,7 @@ import { nip19 } from 'nostr-tools';
|
|||||||
import appConfig from '@/config/appConfig';
|
import appConfig from '@/config/appConfig';
|
||||||
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
|
import MarkdownDisplay from '@/components/markdown/MarkdownDisplay';
|
||||||
const MDDisplay = dynamic(() => import('@uiw/react-markdown-preview'), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const CourseLesson = ({ lesson, course, decryptionPerformed, isPaid, setCompleted }) => {
|
const CourseLesson = ({ lesson, course, decryptionPerformed, isPaid, setCompleted }) => {
|
||||||
const [zapAmount, setZapAmount] = useState(0);
|
const [zapAmount, setZapAmount] = useState(0);
|
||||||
@ -114,7 +110,7 @@ const CourseLesson = ({ lesson, course, decryptionPerformed, isPaid, setComplete
|
|||||||
|
|
||||||
const renderContent = () => {
|
const renderContent = () => {
|
||||||
if (isPaid && decryptionPerformed) {
|
if (isPaid && decryptionPerformed) {
|
||||||
return <MDDisplay className="p-4 rounded-lg w-full" source={lesson.content} />;
|
return <MarkdownDisplay content={lesson.content} className="p-4 rounded-lg w-full" />;
|
||||||
}
|
}
|
||||||
if (isPaid && !decryptionPerformed) {
|
if (isPaid && !decryptionPerformed) {
|
||||||
return (
|
return (
|
||||||
@ -124,7 +120,7 @@ const CourseLesson = ({ lesson, course, decryptionPerformed, isPaid, setComplete
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (lesson?.content) {
|
if (lesson?.content) {
|
||||||
return <MDDisplay className="p-4 rounded-lg w-full" source={lesson.content} />;
|
return <MarkdownDisplay content={lesson.content} className="p-4 rounded-lg w-full" />;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
@ -7,17 +7,13 @@ import { useZapsQuery } from '@/hooks/nostrQueries/zaps/useZapsQuery';
|
|||||||
import { nip19 } from 'nostr-tools';
|
import { nip19 } from 'nostr-tools';
|
||||||
import { Divider } from 'primereact/divider';
|
import { Divider } from 'primereact/divider';
|
||||||
import { getTotalFromZaps } from '@/utils/lightning';
|
import { getTotalFromZaps } from '@/utils/lightning';
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import useWindowWidth from '@/hooks/useWindowWidth';
|
import useWindowWidth from '@/hooks/useWindowWidth';
|
||||||
import appConfig from '@/config/appConfig';
|
import appConfig from '@/config/appConfig';
|
||||||
import useTrackDocumentLesson from '@/hooks/tracking/useTrackDocumentLesson';
|
import useTrackDocumentLesson from '@/hooks/tracking/useTrackDocumentLesson';
|
||||||
import { Toast } from 'primereact/toast';
|
import { Toast } from 'primereact/toast';
|
||||||
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
|
import MarkdownDisplay from '@/components/markdown/MarkdownDisplay';
|
||||||
const MDDisplay = dynamic(() => import('@uiw/react-markdown-preview'), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const DocumentLesson = ({ lesson, course, decryptionPerformed, isPaid, setCompleted }) => {
|
const DocumentLesson = ({ lesson, course, decryptionPerformed, isPaid, setCompleted }) => {
|
||||||
const [zapAmount, setZapAmount] = useState(0);
|
const [zapAmount, setZapAmount] = useState(0);
|
||||||
@ -118,7 +114,7 @@ const DocumentLesson = ({ lesson, course, decryptionPerformed, isPaid, setComple
|
|||||||
|
|
||||||
const renderContent = () => {
|
const renderContent = () => {
|
||||||
if (isPaid && decryptionPerformed) {
|
if (isPaid && decryptionPerformed) {
|
||||||
return <MDDisplay className="p-4 rounded-lg w-full" source={lesson.content} />;
|
return <MarkdownDisplay content={lesson.content} className="p-4 rounded-lg w-full" />;
|
||||||
}
|
}
|
||||||
if (isPaid && !decryptionPerformed) {
|
if (isPaid && !decryptionPerformed) {
|
||||||
return (
|
return (
|
||||||
@ -133,7 +129,7 @@ const DocumentLesson = ({ lesson, course, decryptionPerformed, isPaid, setComple
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (lesson?.content) {
|
if (lesson?.content) {
|
||||||
return <MDDisplay className="p-4 rounded-lg w-full" source={lesson.content} />;
|
return <MarkdownDisplay content={lesson.content} className="p-4 rounded-lg w-full" />;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
@ -4,7 +4,6 @@ import { useImageProxy } from '@/hooks/useImageProxy';
|
|||||||
import { Tag } from 'primereact/tag';
|
import { Tag } from 'primereact/tag';
|
||||||
import GenericButton from '@/components/buttons/GenericButton';
|
import GenericButton from '@/components/buttons/GenericButton';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { nip04, nip19 } from 'nostr-tools';
|
import { nip04, nip19 } from 'nostr-tools';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
@ -18,10 +17,7 @@ import { validateEvent } from '@/utils/nostr';
|
|||||||
import appConfig from '@/config/appConfig';
|
import appConfig from '@/config/appConfig';
|
||||||
import { useEncryptContent } from '@/hooks/encryption/useEncryptContent';
|
import { useEncryptContent } from '@/hooks/encryption/useEncryptContent';
|
||||||
import 'primeicons/primeicons.css';
|
import 'primeicons/primeicons.css';
|
||||||
|
import MarkdownDisplay from '@/components/markdown/MarkdownDisplay';
|
||||||
const MDDisplay = dynamic(() => import('@uiw/react-markdown-preview'), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default function DraftCourseDetails({ processedEvent, draftId, lessons }) {
|
export default function DraftCourseDetails({ processedEvent, draftId, lessons }) {
|
||||||
const [author, setAuthor] = useState(null);
|
const [author, setAuthor] = useState(null);
|
||||||
@ -467,7 +463,7 @@ export default function DraftCourseDetails({ processedEvent, draftId, lessons })
|
|||||||
</div>
|
</div>
|
||||||
<div className="w-[75vw] mx-auto mt-12 p-12 border-t-2 border-gray-300 max-tab:p-0 max-mob:p-0 max-tab:max-w-[100vw] max-mob:max-w-[100vw]">
|
<div className="w-[75vw] mx-auto mt-12 p-12 border-t-2 border-gray-300 max-tab:p-0 max-mob:p-0 max-tab:max-w-[100vw] max-mob:max-w-[100vw]">
|
||||||
{processedEvent?.content && (
|
{processedEvent?.content && (
|
||||||
<MDDisplay className="p-4 rounded-lg" source={processedEvent.content} />
|
<MarkdownDisplay content={processedEvent.content} className="p-4 rounded-lg" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,11 +6,7 @@ import Image from 'next/image';
|
|||||||
import { useImageProxy } from '@/hooks/useImageProxy';
|
import { useImageProxy } from '@/hooks/useImageProxy';
|
||||||
import { formatDateTime, formatUnixTimestamp } from '@/utils/time';
|
import { formatDateTime, formatUnixTimestamp } from '@/utils/time';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import dynamic from 'next/dynamic';
|
import MarkdownDisplay from '@/components/markdown/MarkdownDisplay';
|
||||||
|
|
||||||
const MDDisplay = dynamic(() => import('@uiw/react-markdown-preview'), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const DraftCourseLesson = ({ lesson, course }) => {
|
const DraftCourseLesson = ({ lesson, course }) => {
|
||||||
const [isPublished, setIsPublished] = useState(false);
|
const [isPublished, setIsPublished] = useState(false);
|
||||||
@ -149,7 +145,7 @@ const DraftCourseLesson = ({ lesson, course }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-[75vw] mx-auto mt-12 p-12 border-t-2 border-gray-300 max-tab:p-0 max-mob:p-0 max-tab:max-w-[100vw] max-mob:max-w-[100vw]">
|
<div className="w-[75vw] mx-auto mt-12 p-12 border-t-2 border-gray-300 max-tab:p-0 max-mob:p-0 max-tab:max-w-[100vw] max-mob:max-w-[100vw]">
|
||||||
{lesson?.content && <MDDisplay className="p-4 rounded-lg" source={lesson.content} />}
|
{lesson?.content && <MarkdownDisplay content={lesson.content} className="p-4 rounded-lg" />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -6,7 +6,6 @@ import { useImageProxy } from '@/hooks/useImageProxy';
|
|||||||
import { useZapsQuery } from '@/hooks/nostrQueries/zaps/useZapsQuery';
|
import { useZapsQuery } from '@/hooks/nostrQueries/zaps/useZapsQuery';
|
||||||
import { nip19 } from 'nostr-tools';
|
import { nip19 } from 'nostr-tools';
|
||||||
import { getTotalFromZaps } from '@/utils/lightning';
|
import { getTotalFromZaps } from '@/utils/lightning';
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import { Divider } from 'primereact/divider';
|
import { Divider } from 'primereact/divider';
|
||||||
import appConfig from '@/config/appConfig';
|
import appConfig from '@/config/appConfig';
|
||||||
import useWindowWidth from '@/hooks/useWindowWidth';
|
import useWindowWidth from '@/hooks/useWindowWidth';
|
||||||
@ -14,10 +13,7 @@ import useTrackVideoLesson from '@/hooks/tracking/useTrackVideoLesson';
|
|||||||
import { Toast } from 'primereact/toast';
|
import { Toast } from 'primereact/toast';
|
||||||
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
|
import MarkdownDisplay from '@/components/markdown/MarkdownDisplay';
|
||||||
const MDDisplay = dynamic(() => import('@uiw/react-markdown-preview'), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const VideoLesson = ({ lesson, course, decryptionPerformed, isPaid, setCompleted }) => {
|
const VideoLesson = ({ lesson, course, decryptionPerformed, isPaid, setCompleted }) => {
|
||||||
const [zapAmount, setZapAmount] = useState(0);
|
const [zapAmount, setZapAmount] = useState(0);
|
||||||
@ -170,7 +166,7 @@ const VideoLesson = ({ lesson, course, decryptionPerformed, isPaid, setCompleted
|
|||||||
if (isPaid && decryptionPerformed) {
|
if (isPaid && decryptionPerformed) {
|
||||||
return (
|
return (
|
||||||
<div ref={mdDisplayRef}>
|
<div ref={mdDisplayRef}>
|
||||||
<MDDisplay className="p-0 rounded-lg w-full" source={lesson.content} />
|
<MarkdownDisplay content={lesson.content} className="p-0 rounded-lg w-full" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else if (isPaid && !decryptionPerformed) {
|
} else if (isPaid && !decryptionPerformed) {
|
||||||
@ -196,7 +192,7 @@ const VideoLesson = ({ lesson, course, decryptionPerformed, isPaid, setCompleted
|
|||||||
} else if (lesson?.content) {
|
} else if (lesson?.content) {
|
||||||
return (
|
return (
|
||||||
<div ref={mdDisplayRef}>
|
<div ref={mdDisplayRef}>
|
||||||
<MDDisplay className="p-0 rounded-lg w-full" source={lesson.content} />
|
<MarkdownDisplay content={lesson.content} className="p-0 rounded-lg w-full" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -12,16 +12,12 @@ import { useZapsSubscription } from '@/hooks/nostrQueries/zaps/useZapsSubscripti
|
|||||||
import { getTotalFromZaps } from '@/utils/lightning';
|
import { getTotalFromZaps } from '@/utils/lightning';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
import useWindowWidth from '@/hooks/useWindowWidth';
|
import useWindowWidth from '@/hooks/useWindowWidth';
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import { Toast } from 'primereact/toast';
|
import { Toast } from 'primereact/toast';
|
||||||
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
||||||
import ZapThreadsWrapper from '@/components/ZapThreadsWrapper';
|
import ZapThreadsWrapper from '@/components/ZapThreadsWrapper';
|
||||||
import appConfig from '@/config/appConfig';
|
import appConfig from '@/config/appConfig';
|
||||||
import { nip19 } from 'nostr-tools';
|
import { nip19 } from 'nostr-tools';
|
||||||
|
import MarkdownDisplay from '@/components/markdown/MarkdownDisplay';
|
||||||
const MDDisplay = dynamic(() => import('@uiw/react-markdown-preview'), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const DocumentDetails = ({
|
const DocumentDetails = ({
|
||||||
processedEvent,
|
processedEvent,
|
||||||
@ -234,7 +230,7 @@ const DocumentDetails = ({
|
|||||||
|
|
||||||
const renderContent = () => {
|
const renderContent = () => {
|
||||||
if (decryptedContent) {
|
if (decryptedContent) {
|
||||||
return <MDDisplay className="p-2 rounded-lg w-full" source={decryptedContent} />;
|
return <MarkdownDisplay content={decryptedContent} className="p-2 rounded-lg w-full" />;
|
||||||
}
|
}
|
||||||
if (paidResource && !decryptedContent) {
|
if (paidResource && !decryptedContent) {
|
||||||
return (
|
return (
|
||||||
@ -260,7 +256,7 @@ const DocumentDetails = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (processedEvent?.content) {
|
if (processedEvent?.content) {
|
||||||
return <MDDisplay className="p-4 rounded-lg w-full" source={processedEvent.content} />;
|
return <MarkdownDisplay content={processedEvent.content} className="p-4 rounded-lg w-full" />;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
@ -12,17 +12,13 @@ import { useZapsSubscription } from '@/hooks/nostrQueries/zaps/useZapsSubscripti
|
|||||||
import { getTotalFromZaps } from '@/utils/lightning';
|
import { getTotalFromZaps } from '@/utils/lightning';
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
import useWindowWidth from '@/hooks/useWindowWidth';
|
import useWindowWidth from '@/hooks/useWindowWidth';
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import { Toast } from 'primereact/toast';
|
import { Toast } from 'primereact/toast';
|
||||||
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
import MoreOptionsMenu from '@/components/ui/MoreOptionsMenu';
|
||||||
import ZapThreadsWrapper from '@/components/ZapThreadsWrapper';
|
import ZapThreadsWrapper from '@/components/ZapThreadsWrapper';
|
||||||
import appConfig from '@/config/appConfig';
|
import appConfig from '@/config/appConfig';
|
||||||
import { nip19 } from 'nostr-tools';
|
import { nip19 } from 'nostr-tools';
|
||||||
import { Buffer } from 'buffer';
|
import { Buffer } from 'buffer';
|
||||||
|
import MarkdownDisplay from '@/components/markdown/MarkdownDisplay';
|
||||||
const MDDisplay = dynamic(() => import('@uiw/react-markdown-preview'), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const VideoDetails = ({
|
const VideoDetails = ({
|
||||||
processedEvent,
|
processedEvent,
|
||||||
@ -234,7 +230,7 @@ const VideoDetails = ({
|
|||||||
|
|
||||||
const renderContent = () => {
|
const renderContent = () => {
|
||||||
if (decryptedContent) {
|
if (decryptedContent) {
|
||||||
return <MDDisplay className="p-0 rounded-lg w-full" source={decryptedContent} />;
|
return <MarkdownDisplay content={decryptedContent} className="p-0 rounded-lg w-full" />;
|
||||||
}
|
}
|
||||||
if (paidResource && !decryptedContent) {
|
if (paidResource && !decryptedContent) {
|
||||||
return (
|
return (
|
||||||
@ -267,7 +263,7 @@ const VideoDetails = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (processedEvent?.content) {
|
if (processedEvent?.content) {
|
||||||
return <MDDisplay className="p-0 rounded-lg w-full" source={processedEvent.content} />;
|
return <MarkdownDisplay content={processedEvent.content} className="p-0 rounded-lg w-full" />;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
27
src/components/markdown/MarkdownDisplay.js
Normal file
27
src/components/markdown/MarkdownDisplay.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
import rehypeRaw from 'rehype-raw';
|
||||||
|
import remarkGfm from 'remark-gfm';
|
||||||
|
import remarkBreaks from 'remark-breaks';
|
||||||
|
import 'github-markdown-css/github-markdown-dark.css';
|
||||||
|
|
||||||
|
const MarkdownDisplay = ({ content, className = "" }) => {
|
||||||
|
if (!content) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`markdown-body bg-gray-900 ${className}`}>
|
||||||
|
<ReactMarkdown
|
||||||
|
remarkPlugins={[remarkGfm, remarkBreaks]}
|
||||||
|
rehypePlugins={[rehypeRaw]}
|
||||||
|
components={{
|
||||||
|
a: ({node, ...props}) => <a target="_blank" rel="noopener noreferrer" {...props} />,
|
||||||
|
img: ({node, ...props}) => <img {...props} className="max-w-full rounded my-2" />
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{content}
|
||||||
|
</ReactMarkdown>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default MarkdownDisplay;
|
@ -13,16 +13,12 @@ import { nip19 } from 'nostr-tools';
|
|||||||
import { useToast } from '@/hooks/useToast';
|
import { useToast } from '@/hooks/useToast';
|
||||||
import { ProgressSpinner } from 'primereact/progressspinner';
|
import { ProgressSpinner } from 'primereact/progressspinner';
|
||||||
import { useDecryptContent } from '@/hooks/encryption/useDecryptContent';
|
import { useDecryptContent } from '@/hooks/encryption/useDecryptContent';
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import ZapThreadsWrapper from '@/components/ZapThreadsWrapper';
|
import ZapThreadsWrapper from '@/components/ZapThreadsWrapper';
|
||||||
import appConfig from '@/config/appConfig';
|
import appConfig from '@/config/appConfig';
|
||||||
import useWindowWidth from '@/hooks/useWindowWidth';
|
import useWindowWidth from '@/hooks/useWindowWidth';
|
||||||
import MenuTab from '@/components/menutab/MenuTab';
|
import MenuTab from '@/components/menutab/MenuTab';
|
||||||
import { Tag } from 'primereact/tag';
|
import { Tag } from 'primereact/tag';
|
||||||
|
import MarkdownDisplay from '@/components/markdown/MarkdownDisplay';
|
||||||
const MDDisplay = dynamic(() => import('@uiw/react-markdown-preview'), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const useCourseData = (ndk, fetchAuthor, router) => {
|
const useCourseData = (ndk, fetchAuthor, router) => {
|
||||||
const [course, setCourse] = useState(null);
|
const [course, setCourse] = useState(null);
|
||||||
@ -470,6 +466,7 @@ const Course = () => {
|
|||||||
isPaid={paidCourse}
|
isPaid={paidCourse}
|
||||||
setCompleted={setCompleted}
|
setCompleted={setCompleted}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
);
|
);
|
||||||
} else if (lesson.type === 'video' && !lesson.topics?.includes('document')) {
|
} else if (lesson.type === 'video' && !lesson.topics?.includes('document')) {
|
||||||
return (
|
return (
|
||||||
@ -496,7 +493,7 @@ const Course = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="mx-auto px-8 max-mob:px-1 mb-12 mt-4">
|
<div className="mx-auto px-8 max-mob:px-0 mb-12 mt-4">
|
||||||
{/* Tab navigation using MenuTab component */}
|
{/* Tab navigation using MenuTab component */}
|
||||||
<div className="sticky z-10 bg-transparent border-b border-gray-700/30"
|
<div className="sticky z-10 bg-transparent border-b border-gray-700/30"
|
||||||
style={{
|
style={{
|
||||||
@ -526,25 +523,25 @@ const Course = () => {
|
|||||||
{/* Content tab content */}
|
{/* Content tab content */}
|
||||||
<div className={`${activeTab === 'content' ? 'block' : 'hidden'}`}>
|
<div className={`${activeTab === 'content' ? 'block' : 'hidden'}`}>
|
||||||
{uniqueLessons.length > 0 && uniqueLessons[activeIndex] ? (
|
{uniqueLessons.length > 0 && uniqueLessons[activeIndex] ? (
|
||||||
<div className="bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm overflow-hidden">
|
<div className="bg-gray-900 rounded-lg shadow-sm overflow-hidden">
|
||||||
{renderLesson(uniqueLessons[activeIndex])}
|
{renderLesson(uniqueLessons[activeIndex])}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="text-center bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 p-8">
|
<div className="text-center bg-gray-900 rounded-lg p-8">
|
||||||
<p>Select a lesson from the sidebar to begin learning.</p>
|
<p>Select a lesson from the sidebar to begin learning.</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{course?.content && (
|
{course?.content && (
|
||||||
<div className="mt-8 bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm">
|
<div className="mt-8 bg-gray-900 rounded-lg shadow-sm">
|
||||||
<MDDisplay className="p-4 rounded-lg" source={course.content} />
|
<MarkdownDisplay content={course.content} className="p-4 rounded-lg" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Lessons tab - only visible on mobile */}
|
{/* Lessons tab - only visible on mobile */}
|
||||||
<div className={`${activeTab === 'lessons' && isMobileView ? 'block' : 'hidden'}`}>
|
<div className={`${activeTab === 'lessons' && isMobileView ? 'block' : 'hidden'}`}>
|
||||||
<div className="text-center bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700 p-8">
|
<div className="text-center bg-gray-900 rounded-lg p-8">
|
||||||
<p>Please use the sidebar to navigate lessons.</p>
|
<p>Please use the sidebar to navigate lessons.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,15 +15,11 @@ import { formatDateTime } from '@/utils/time';
|
|||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import useResponsiveImageDimensions from '@/hooks/useResponsiveImageDimensions';
|
import useResponsiveImageDimensions from '@/hooks/useResponsiveImageDimensions';
|
||||||
import 'primeicons/primeicons.css';
|
import 'primeicons/primeicons.css';
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
import { validateEvent } from '@/utils/nostr';
|
import { validateEvent } from '@/utils/nostr';
|
||||||
import appConfig from '@/config/appConfig';
|
import appConfig from '@/config/appConfig';
|
||||||
import { useIsAdmin } from '@/hooks/useIsAdmin';
|
import { useIsAdmin } from '@/hooks/useIsAdmin';
|
||||||
import { useEncryptContent } from '@/hooks/encryption/useEncryptContent';
|
import { useEncryptContent } from '@/hooks/encryption/useEncryptContent';
|
||||||
|
import MarkdownDisplay from '@/components/markdown/MarkdownDisplay';
|
||||||
const MDDisplay = dynamic(() => import('@uiw/react-markdown-preview'), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default function Draft() {
|
export default function Draft() {
|
||||||
const [draft, setDraft] = useState(null);
|
const [draft, setDraft] = useState(null);
|
||||||
@ -433,7 +429,7 @@ export default function Draft() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-[75vw] mx-auto mt-12 p-12 border-t-2 border-gray-300 max-tab:p-0 max-mob:p-0 max-tab:max-w-[100vw] max-mob:max-w-[100vw]">
|
<div className="w-[75vw] mx-auto mt-12 p-12 border-t-2 border-gray-300 max-tab:p-0 max-mob:p-0 max-tab:max-w-[100vw] max-mob:max-w-[100vw]">
|
||||||
{draft?.content && <MDDisplay className="p-4 rounded-lg" source={draft.content} />}
|
{draft?.content && <MarkdownDisplay content={draft.content} className="p-4 rounded-lg" />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user