@@ -14,51 +14,105 @@ import { Badge } from "@/components/ui/badge"
1414
1515
1616
17+ import { publications } from "@/data/publications"
18+ import { type_mapping } from "@/data/mapping"
19+
20+
21+
22+ function isWithinLastNMonths ( time : string , months = 3 ) {
23+ const pubDate = new Date ( time . replace ( / \. / g, '-' ) ) ;
24+ const now = new Date ( ) ;
25+
26+ const past = new Date ( ) ;
27+ past . setMonth ( now . getMonth ( ) - months ) ;
28+
29+ return pubDate >= past && pubDate <= now ;
30+ }
31+ const recentPublications = publications
32+ . filter ( pub => pub . time && isWithinLastNMonths ( pub . time , 3 ) )
33+ . sort (
34+ ( a , b ) =>
35+ new Date ( b . time . replace ( / \. / g, '-' ) ) . getTime ( ) -
36+ new Date ( a . time . replace ( / \. / g, '-' ) ) . getTime ( )
37+ ) ;
38+
39+
40+
41+ type NewsItem = {
42+ date : string ;
43+ content : string ;
44+ links ?: { label : string ; url : string } [ ] ;
45+ } ;
46+ function getPublicationLinks ( pub : {
47+ link ?: string ;
48+ icon ?: { type : string ; link : string } [ ] ;
49+ } ) {
50+ const links : { label : string ; url : string } [ ] = [ ] ;
51+
52+ // Paper 主链接
53+ if ( pub . link ) {
54+ links . push ( {
55+ label : 'Paper' ,
56+ url : pub . link ,
57+ } ) ;
58+ }
59+
60+ // icon 里的所有链接,全部保留
61+ if ( Array . isArray ( pub . icon ) ) {
62+ pub . icon . forEach ( icon => {
63+ if ( icon . type === 'cite' ) return ;
64+ links . push ( {
65+ label : type_mapping [ icon . type ] ??
66+ icon . type . charAt ( 0 ) . toUpperCase ( ) + icon . type . slice ( 1 ) ,
67+ url : icon . link ,
68+ } ) ;
69+ } ) ;
70+ }
71+
72+ return links ;
73+ }
74+ const publicationNews : NewsItem [ ] = recentPublications . map ( pub => ( {
75+ date : pub . time ,
76+ content : `${ pub . title } has been published.` ,
77+ links : getPublicationLinks ( pub ) ,
78+ } ) ) ;
79+
80+
81+
1782export function News ( ) {
1883 return (
1984 < div className = "w-full px-6 flex justify-center mt-12" >
2085 < div className = "w-full max-w-7xl flex flex-col gap-6 leading-relaxed" >
2186 < ul className = "space-y-6" >
22- < li className = "flex items-center gap-1 flex-wrap" >
23- { /* <Badge variant="outline"> */ }
24- < Badge variant = "default" >
25- 2025.09.19
26- </ Badge >
27- GO-1 is now open source on
28- < Link className = "text-o-blue animated-underline" href = "https://github.com/OpenDriveLab/AgiBot-World" target = "_blank" > [GitHub]</ Link >
29- with our technical blog available at
30- < Link className = "text-o-blue animated-underline" href = "https://opendrivelab.com/OpenGO1" target = "_blank" > OpenGO1</ Link >
31- .
32- </ li >
33- < li className = "flex items-center gap-1 flex-wrap" >
34- { /* <Badge variant="outline"> */ }
35- < Badge variant = "default" >
36- 2025.07.01
37- </ Badge >
38- DetAny3D is now open source. Check it out on:
39- < Link className = "text-o-blue animated-underline" href = "https://github.com/OpenDriveLab/DetAny3D" target = "_blank" > github.com/OpenDriveLab/DetAny3D</ Link >
40- .
41- </ li >
42- < li className = "flex items-center gap-1 flex-wrap" >
43- < Badge variant = "default" >
44- 2025.07.01
45- </ Badge >
46- < Link className = "text-o-blue animated-underline" href = "/challenge2025" > [AGC 2025]</ Link >
47- The ICCV phase is ON! Explore the
48- < Link className = "text-o-blue animated-underline" href = "/challenge2025//#navsim-e2e-driving" > NAVSIM v2 End-to-End Driving Challenge</ Link >
49- and the
50- < Link className = "text-o-blue animated-underline" href = "/challenge2025//#1x-wm" > World Model Challenge by 1X</ Link >
51- .
52- </ li >
53- < li className = "flex items-center gap-1 flex-wrap" >
54- < Badge variant = "default" >
55- 2025.07.01
56- </ Badge >
57- < Link className = "text-o-blue animated-underline" href = "/challenge2025" > [AGC 2025]</ Link >
58- The IROS phase is ON! Explore the
59- < Link className = "text-o-blue animated-underline" href = "/challenge2025//#agibot-world" > AgiBot World Challenge</ Link >
60- .
61- </ li >
87+ {
88+ publicationNews . map ( ( item , idx ) => (
89+ < div key = { idx } className = "flex flex-row items-center" >
90+ < Badge variant = "default" className = "mr-2 w-[88px] text-center shrink-0" >
91+ { item . date }
92+ </ Badge >
93+ < div className = "flex flex-row items-center flex-wrap" >
94+ < span >
95+ { item . content }
96+ </ span >
97+ < span className = "select-none" >
98+
99+ </ span >
100+ {
101+ item . links ?. map ( ( link , index ) => (
102+ < span key = { index } className = "flex items-center" >
103+ < Link className = "text-o-blue animated-underline" href = { link . url } target = { link . url . startsWith ( 'http' ) ? '_blank' : '_self' } >
104+ { link . label }
105+ </ Link >
106+ { index < ( item . links ?? [ ] ) . length - 1 && (
107+ < span className = "text-xs mx-2" > | </ span >
108+ ) }
109+ </ span >
110+ ) )
111+ }
112+ </ div >
113+ </ div >
114+ ) )
115+ }
62116 </ ul >
63117 </ div >
64118 </ div >
0 commit comments