1
1
use std:: collections:: HashMap ;
2
2
3
- use leptos:: {
4
- component, create_local_resource, error:: Result , island, serde_json:: json, view, Fragment ,
5
- IntoView , SignalGet ,
6
- } ;
3
+ use leptos:: { component, serde_json:: json, view, Await , IntoView } ;
7
4
use serde:: { Deserialize , Serialize } ;
8
5
9
6
use crate :: components:: ContributorCard ;
10
7
8
+ // Test this query on: https://docs.github.com/es/graphql/overview/explorer
11
9
const GRAPH_QUERY : & str = r#"
12
10
query OrganizationContributors {
13
11
organization(login: "RustLangES") {
@@ -59,15 +57,18 @@ pub struct ContributionCollection {
59
57
issues : u64 ,
60
58
#[ serde( rename = "totalRepositoryContributions" ) ]
61
59
repository : u64 ,
60
+ #[ serde( skip) ]
61
+ total : u64 ,
62
62
}
63
63
64
- pub async fn fetch_contributors ( ) -> Result < Vec < Contributor > > {
64
+ pub async fn fetch_contributors ( ) -> Vec < Contributor > {
65
65
let request_body = json ! ( {
66
66
"query" : GRAPH_QUERY ,
67
67
} ) ;
68
68
69
69
let mut headers = reqwest:: header:: HeaderMap :: new ( ) ;
70
70
71
+ headers. append ( "User-Agent" , "RustLangES Automation Agent" . parse ( ) . unwrap ( ) ) ;
71
72
headers. append (
72
73
"Authorization" ,
73
74
format ! ( "Bearer {}" , env!( "GITHUB_API_TOKEN" ) )
@@ -77,15 +78,22 @@ pub async fn fetch_contributors() -> Result<Vec<Contributor>> {
77
78
78
79
let client = reqwest:: ClientBuilder :: new ( )
79
80
. default_headers ( headers)
80
- . build ( ) ?;
81
+ . build ( )
82
+ . unwrap ( ) ;
81
83
82
- let res: leptos :: serde_json :: Value = client
84
+ let res = client
83
85
. post ( "https://api.github.com/graphql" )
84
86
. json ( & request_body)
85
87
. send ( )
86
- . await ?
87
- . json ( )
88
- . await ?;
88
+ . await
89
+ . unwrap ( )
90
+ . text ( )
91
+ . await
92
+ . unwrap ( ) ;
93
+
94
+ leptos:: logging:: log!( "Raw: {res:?}" ) ;
95
+
96
+ let res: leptos:: serde_json:: Value = leptos:: serde_json:: from_str ( & res) . unwrap ( ) ;
89
97
90
98
let mut res = res[ "data" ] [ "organization" ] [ "repositories" ] [ "nodes" ]
91
99
. as_array ( )
@@ -101,57 +109,41 @@ pub async fn fetch_contributors() -> Result<Vec<Contributor>> {
101
109
o. contributions_collection . as_mut ( ) ,
102
110
c. contributions_collection . as_ref ( ) ,
103
111
) {
104
- ( Some ( o) , Some ( c) ) => o. commits += c. commits ,
105
- ( Some ( o) , None ) => o. commits += 1 ,
112
+ ( Some ( o) , Some ( c) ) => {
113
+ o. total = o. total . max (
114
+ ( o. commits + o. issues + o. pull_request + o. repository )
115
+ . max ( c. commits + c. issues + c. pull_request + c. repository ) ,
116
+ )
117
+ }
118
+ ( Some ( o) , None ) => o. total = 1 ,
106
119
_ => { }
107
120
}
108
121
} )
109
122
. or_insert ( c) ;
110
123
prev
111
124
} )
112
125
. into_values ( )
126
+ . filter ( |c| {
127
+ c. contributions_collection
128
+ . as_ref ( )
129
+ . is_some_and ( |cc| cc. total != 0 )
130
+ } )
113
131
. collect :: < Vec < _ > > ( ) ;
114
132
115
133
res. sort_by_key ( |a| {
116
134
a. contributions_collection
117
135
. as_ref ( )
118
- . map ( |c| c. repository )
136
+ . map ( |c| c. total )
119
137
. unwrap_or ( 1 )
120
138
} ) ;
121
139
122
140
res. reverse ( ) ;
123
141
124
- Ok ( res)
142
+ res
125
143
}
126
144
127
- #[ island ]
145
+ #[ component ]
128
146
pub fn Contributors ( ) -> impl IntoView {
129
- let contributors = create_local_resource ( move || ( ) , |( ) | fetch_contributors ( ) ) ;
130
-
131
- let contributorMapper = |item : & Contributor | {
132
- view ! {
133
- <ContributorCard
134
- name=item. login. clone( )
135
- description=item. bio. clone( )
136
- link=item. url. clone( )
137
- brand_src=item. avatar_url. clone( )
138
- twitter=item. twitter_username. clone( )
139
- location=item. location. clone( )
140
- contributions=item. contributions_collection. as_ref( ) . map( |c| c. commits) . unwrap_or( 1 )
141
- />
142
- }
143
- } ;
144
-
145
- let contributors_view = move || {
146
- let result = contributors
147
- . get ( ) ?
148
- . ok ( ) ?
149
- . iter ( )
150
- . map ( contributorMapper)
151
- . collect :: < Fragment > ( ) ;
152
- Some ( result. into_view ( ) )
153
- } ;
154
-
155
147
view ! {
156
148
<section class="bg-orange-300/30 dark:bg-transparent py-16 min-h-[80vh]" >
157
149
<div class="flex flex-col gap-y-6 container mx-auto px-4" >
@@ -160,7 +152,22 @@ pub fn Contributors() -> impl IntoView {
160
152
<span class="font-alfa-slab text-orange-500" >"Colaboradores" </span>
161
153
</h2>
162
154
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-5 gap-6" >
163
- { contributors_view}
155
+ <Await
156
+ future=|| fetch_contributors( )
157
+ let : contributors
158
+ >
159
+ { contributors. iter( ) . map( |item| view! {
160
+ <ContributorCard
161
+ name=item. login. clone( )
162
+ description=item. bio. clone( )
163
+ link=item. url. clone( )
164
+ brand_src=item. avatar_url. clone( )
165
+ twitter=item. twitter_username. clone( )
166
+ location=item. location. clone( )
167
+ contributions=item. contributions_collection. as_ref( ) . map( |c| c. total) . unwrap_or( 1 )
168
+ />
169
+ } ) . collect:: <Vec <_>>( ) }
170
+ </Await >
164
171
</div>
165
172
</div>
166
173
</section>
0 commit comments