11import React from "react" ;
2- import { Card , List , Typography , Image , Collapse } from "antd" ;
2+ import {
3+ Card ,
4+ List ,
5+ Typography ,
6+ Image ,
7+ Collapse ,
8+ Descriptions ,
9+ Tag ,
10+ Space ,
11+ } from "antd" ;
312
413const { Title, Paragraph, Link, Text } = Typography ;
514const { Panel } = Collapse ;
@@ -12,12 +21,7 @@ interface RedditChild {
1221interface RedditListing {
1322 kind : string ;
1423 data : {
15- after : string | null ;
16- dist : number | null ;
17- modhash : string ;
18- geo_filter : string ;
1924 children : RedditChild [ ] ;
20- before : string | null ;
2125 } ;
2226}
2327
@@ -30,20 +34,43 @@ interface RedditPost {
3034 author : string ;
3135 score : number ;
3236 selftext ?: string ;
37+ created_utc : number ;
3338}
3439
3540interface RedditComment {
3641 id : string ;
3742 author : string ;
3843 score : number ;
3944 body : string ;
45+ created_utc : number ;
4046 replies ?: RedditListing | string ;
4147}
4248
4349interface RedditListingProps {
4450 data : RedditListing [ ] ;
4551}
4652
53+ const timeAgo = ( utc : number ) => {
54+ const seconds = Math . floor ( Date . now ( ) / 1000 - utc ) ;
55+ const rtf = new Intl . RelativeTimeFormat ( "en" , { numeric : "auto" } ) ;
56+
57+ const intervals = [
58+ { unit : "year" , seconds : 31536000 } ,
59+ { unit : "month" , seconds : 2592000 } ,
60+ { unit : "week" , seconds : 604800 } ,
61+ { unit : "day" , seconds : 86400 } ,
62+ { unit : "hour" , seconds : 3600 } ,
63+ { unit : "minute" , seconds : 60 } ,
64+ ] ;
65+
66+ for ( const interval of intervals ) {
67+ const count = Math . floor ( seconds / interval . seconds ) ;
68+ if ( count >= 1 ) return rtf . format ( - count , interval . unit as any ) ;
69+ }
70+
71+ return rtf . format ( - seconds , "second" ) ;
72+ } ;
73+
4774const RedditListing : React . FC < RedditListingProps > = ( { data } ) => {
4875 if ( ! data || ! Array . isArray ( data ) ) return null ;
4976
@@ -53,25 +80,39 @@ const RedditListing: React.FC<RedditListingProps> = ({ data }) => {
5380 < Card
5481 key = { d . id }
5582 title = {
56- < Link href = { `https://reddit.com${ d . permalink } ` } target = "_blank" >
57- { d . title }
58- </ Link >
83+ < Space >
84+ < Link href = { `https://reddit.com${ d . permalink } ` } target = "_blank" >
85+ { d . title }
86+ </ Link >
87+ < Tag color = "blue" > { timeAgo ( d . created_utc ) } </ Tag >
88+ </ Space >
5989 }
60- style = { { marginBottom : 16 } }
90+ style = { { marginBottom : 24 } }
6191 >
62- { d . thumbnail && d . thumbnail . startsWith ( "http" ) && (
63- < Image width = { 140 } src = { d . thumbnail } alt = "thumbnail" />
64- ) }
65- < Paragraph >
66- < Text strong > Subreddit:</ Text > { d . subreddit_name_prefixed }
67- </ Paragraph >
68- < Paragraph >
69- < Text strong > Author:</ Text > { d . author }
70- </ Paragraph >
71- < Paragraph >
72- < Text strong > Score:</ Text > { d . score }
73- </ Paragraph >
74- { d . selftext && < Paragraph > { d . selftext } </ Paragraph > }
92+ < Space direction = "vertical" size = "middle" style = { { width : "100%" } } >
93+ { d . thumbnail && d . thumbnail . startsWith ( "http" ) && (
94+ < Image width = { 200 } src = { d . thumbnail } alt = "thumbnail" />
95+ ) }
96+ < Descriptions column = { 1 } bordered size = "small" >
97+ < Descriptions . Item label = "Subreddit" >
98+ { d . subreddit_name_prefixed }
99+ </ Descriptions . Item >
100+ < Descriptions . Item label = "Author" >
101+ < Link href = { `https://reddit.com/user/${ d . author } ` } target = "_blank" >
102+ u/{ d . author }
103+ </ Link >
104+ </ Descriptions . Item >
105+ < Descriptions . Item label = "Score" >
106+ < Tag color = { d . score > 1 ? "geekblue" : "volcano" } > { d . score } </ Tag >
107+ </ Descriptions . Item >
108+ < Descriptions . Item label = "Created" >
109+ { timeAgo ( d . created_utc ) }
110+ </ Descriptions . Item >
111+ </ Descriptions >
112+ { d . selftext && (
113+ < Paragraph style = { { marginTop : 16 } } > { d . selftext } </ Paragraph >
114+ ) }
115+ </ Space >
75116 </ Card >
76117 ) ;
77118 } ;
@@ -82,49 +123,50 @@ const RedditListing: React.FC<RedditListingProps> = ({ data }) => {
82123 < Collapse key = { d . id } style = { { marginBottom : 8 } } >
83124 < Panel
84125 header = {
85- < span >
86- { d . author } | Score: { d . score }
87- </ span >
126+ < Space >
127+ < Text strong > { d . author } </ Text >
128+ < Tag color = { d . score >= 1 ? "geekblue" : "volcano" } > { d . score } </ Tag >
129+ < Text type = "secondary" > { timeAgo ( d . created_utc ) } </ Text >
130+ </ Space >
88131 }
89132 key = { d . id }
90133 >
91134 < Paragraph > { d . body } </ Paragraph >
92- { d . replies && typeof d . replies !== 'string' && d . replies . data && d . replies . data . children . length > 0 && (
93- < div style = { { marginLeft : 24 } } >
94- { d . replies . data . children . map ( ( child ) =>
95- child . kind === "t1" ? renderComment ( child ) : null
96- ) }
97- </ div >
98- ) }
135+ { d . replies &&
136+ typeof d . replies !== "string" &&
137+ d . replies . data &&
138+ d . replies . data . children . length > 0 && (
139+ < div style = { { marginLeft : 24 } } >
140+ { d . replies . data . children . map ( ( child ) =>
141+ child . kind === "t1" ? renderComment ( child ) : null
142+ ) }
143+ </ div >
144+ ) }
99145 </ Panel >
100146 </ Collapse >
101147 ) ;
102148 } ;
103149
104150 return (
105151 < List
106- header = { < Title level = { 3 } > Reddit Listing </ Title > }
152+ header = { < Title level = { 3 } > 📜 Archived Reddit Thread </ Title > }
107153 dataSource = { data }
108- renderItem = { ( item ) => {
109- const children = item . data . children ;
110- return (
111- < div key = { item . kind } >
112- { children . map ( ( child ) => {
113- if ( child . kind === "t3" ) {
114- return renderPost ( child ) ;
115- } else if ( child . kind === "t1" ) {
116- return renderComment ( child ) ;
117- } else {
118- return null ;
119- }
120- } ) }
121- </ div >
122- ) ;
123- } }
154+ renderItem = { ( item ) => (
155+ < div key = { item . kind } >
156+ { item . data . children . map ( ( child ) => {
157+ if ( child . kind === "t3" ) {
158+ return renderPost ( child ) ;
159+ } else if ( child . kind === "t1" ) {
160+ return renderComment ( child ) ;
161+ } else {
162+ return null ;
163+ }
164+ } ) }
165+ </ div >
166+ ) }
124167 />
125168 ) ;
126169} ;
127170
128171const RedditPostRenderer = RedditListing ;
129-
130- export default RedditListing ;
172+ export default RedditPostRenderer ;
0 commit comments