1
1
import Link from "next/link" ;
2
+ import dynamic from "next/dynamic" ;
2
3
import { useProfile } from "nostr-react" ;
3
4
import { Event , nip19 } from "nostr-tools" ;
4
- import {
5
- DetailedHTMLProps ,
6
- FC ,
7
- LiHTMLAttributes ,
8
- ReactNode ,
9
- useContext ,
10
- } from "react" ;
5
+ import { DetailedHTMLProps , FC , LiHTMLAttributes , ReactNode } from "react" ;
11
6
import { BsFillFileEarmarkCodeFill , BsFillTagFill } from "react-icons/bs" ;
12
7
import { FaCalendarAlt } from "react-icons/fa" ;
13
8
import { DUMMY_PROFILE_API } from "../../utils/constants" ;
14
9
import { shortenHash } from "../../lib/utils" ;
15
- import { PostDirContext } from "../../context/post-dir-provider" ;
16
10
import { getTagValues } from "../../lib/utils" ;
11
+ import "@uiw/react-textarea-code-editor/dist.css" ;
17
12
18
13
interface NoteProps
19
14
extends DetailedHTMLProps < LiHTMLAttributes < HTMLLIElement > , HTMLLIElement > {
@@ -22,51 +17,49 @@ interface NoteProps
22
17
dateOnly ?: boolean ;
23
18
}
24
19
20
+ const CodeEditor = dynamic (
21
+ ( ) => import ( "@uiw/react-textarea-code-editor" ) . then ( ( mod ) => mod . default ) ,
22
+ { ssr : true }
23
+ ) ;
24
+
25
25
const Card : FC < NoteProps > = ( {
26
26
event,
27
27
profile = false ,
28
28
dateOnly = false ,
29
29
...props
30
30
} ) => {
31
31
const { tags, content, created_at : createdAt , id : noteId } = event ;
32
- const { isCol } = useContext ( PostDirContext ) ;
33
32
34
33
const { data } = useProfile ( {
35
34
pubkey : event . pubkey ,
36
35
} ) ;
37
36
38
37
const npub = nip19 . npubEncode ( event . pubkey ) ;
39
38
40
- // let actualTags: any = getTagValues("tags");
39
+ const title = getTagValues ( "subject" , tags ) ;
40
+ const filetype = getTagValues ( "filetype" , tags ) ;
41
+ const actualTags = getTagValues ( "tags" , tags ) ;
41
42
42
- // if (actualTags) {
43
- // actualTags = actualTags.split(",");
44
- // }
43
+ function setupMarkdown ( content : string ) {
44
+ var md = require ( "markdown-it" ) ( ) ;
45
+ var result = md . render ( content ) ;
46
+ return result ;
47
+ }
45
48
46
- const title = getTagValues ( "subject" , tags ) ;
47
- const markdownImageContent =
48
- / ! \[ [ ^ \] ] * \] \( (?< filename > .* ?) (? = \" | \) ) (?< title > \" .* \" ) ? \) / g. exec ( content ) ;
49
+ const MAX_LENGTH = 300 ;
50
+
51
+ const markdown =
52
+ content . length > MAX_LENGTH
53
+ ? setupMarkdown ( content . slice ( 0 , MAX_LENGTH ) ) . concat ( "...read more" )
54
+ : setupMarkdown ( content . slice ( 0 , MAX_LENGTH ) ) ;
49
55
50
56
return (
51
57
< li
52
58
className = "rounded-md hover:shadow-sm hover:scale-101 transition-transform hover:shadow-accent bg-secondary text-accent text-left"
53
59
{ ...props }
54
60
>
55
- < Link
56
- href = { `/${ nip19 . noteEncode ( noteId ! ) } ` }
57
- className = { `p-5 flex gap-4 justify-between flex-col-reverse ${
58
- isCol ? "" : "md:flex-row"
59
- } `}
60
- >
61
- < div
62
- className = { `flex flex-col gap-3
63
- ${
64
- markdownImageContent ?. groups ?. filename && ! isCol
65
- ? "md:max-w-[65%] flex-[.75]"
66
- : "max-w-full"
67
- }
68
- ` }
69
- >
61
+ < Link href = { `/${ nip19 . noteEncode ( noteId ! ) } ` } className = "p-5 block" >
62
+ < div className = "flex flex-col gap-3 w-full" >
70
63
{ title ? (
71
64
< h3 className = "text-2xl font-semibold text-light twolines" >
72
65
{ title }
@@ -90,22 +83,33 @@ const Card: FC<NoteProps> = ({
90
83
</ div >
91
84
) : null }
92
85
< DatePosted dateOnly = { dateOnly } timestamp = { createdAt } />
93
- < FileType type = { getTagValues ( "filetype" , tags ) } />
94
- { /* {actualTags.length > 1 ? <NoteTags tags={actualTags} /> : null } */ }
86
+ < FileType type = { filetype } />
87
+ </ div >
88
+ < div >
89
+ { actualTags . length > 1 ? (
90
+ < NoteTags tags = { actualTags . split ( "," ) } />
91
+ ) : null }
95
92
</ div >
96
- < div className = "flex flex-col sm:flex-row gap-5 opacity-70" >
97
- < div className = "twolines opacity-70" > { content } </ div >
93
+ < div className = "flex flex-col sm:flex-row gap-5 w-full bg-primary max-h-[50vh] overflow-hidden rounded-md" >
94
+ { filetype === "markdown" ? (
95
+ < div className = "w-full max-w-full p-4 prose prose-sm prose-invert prose-img:h-[20vh] prose-img:w-auto prose-img:object-cover prose-img:mx-auto" >
96
+ < div dangerouslySetInnerHTML = { { __html : markdown } } />
97
+ </ div >
98
+ ) : (
99
+ < CodeEditor
100
+ className = "w-full outline-none min-h-full pointer-events-none"
101
+ value = { content }
102
+ language = { filetype }
103
+ autoCapitalize = "none"
104
+ disabled
105
+ padding = { 25 }
106
+ style = { {
107
+ fontSize : 15 ,
108
+ } }
109
+ />
110
+ ) }
98
111
</ div >
99
112
</ div >
100
- { markdownImageContent ?. groups ?. filename ? (
101
- < img
102
- className = { `rounded-md self-center w-full h-auto object-cover flex-[.25] ${
103
- isCol ? "" : "md:w-1/3"
104
- } `}
105
- src = { markdownImageContent ?. groups ?. filename }
106
- alt = { markdownImageContent ?. groups ?. title }
107
- />
108
- ) : null }
109
113
</ Link >
110
114
</ li >
111
115
) ;
0 commit comments