|
1 |
| -use futures::future::join_all; |
2 |
| -use leptos::{create_local_resource, error::Result, island, view, Fragment, IntoView, SignalGet}; |
| 1 | +#[cfg(not(debug_assertions))] |
| 2 | +use leptos::{create_local_resource, SignalGet}; |
| 3 | +use leptos::{error::Result, island, serde_json::json, view, Fragment, IntoView}; |
3 | 4 | use serde::{Deserialize, Serialize};
|
4 | 5 |
|
5 |
| -use crate::{components::ContributorCard, error, log}; |
| 6 | +use crate::components::ContributorCard; |
| 7 | + |
| 8 | +#[cfg(not(debug_assertions))] |
| 9 | +const GRAPH_QUERY: &str = r#" |
| 10 | +query OrganizationContributors { |
| 11 | + organization(login: "RustLangES") { |
| 12 | + repositories(first: 100) { |
| 13 | + nodes { |
| 14 | + collaborators(first: 100) { |
| 15 | + nodes { |
| 16 | + login |
| 17 | + avatarUrl |
| 18 | + url |
| 19 | + bio |
| 20 | + twitterUsername |
| 21 | + location |
| 22 | + contributionsCollection { |
| 23 | + totalCommitContributions |
| 24 | + } |
| 25 | + } |
| 26 | + } |
| 27 | + } |
| 28 | + } |
| 29 | + } |
| 30 | +} |
| 31 | +"#; |
6 | 32 |
|
7 | 33 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
8 | 34 | pub struct Contributor {
|
9 | 35 | login: String,
|
10 | 36 | avatar_url: String,
|
11 |
| - html_url: String, |
| 37 | + url: String, |
12 | 38 | bio: Option<String>,
|
13 | 39 | twitter_username: Option<String>,
|
14 | 40 | location: Option<String>,
|
15 |
| - contributions: Option<i32>, |
| 41 | + contributions_collection: ContributionCollection, |
| 42 | +} |
| 43 | + |
| 44 | +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] |
| 45 | +pub struct ContributionCollection { |
| 46 | + total_commit_contributions: u64, |
16 | 47 | }
|
17 | 48 |
|
| 49 | +#[cfg(not(debug_assertions))] |
18 | 50 | async fn fetch_contributors() -> Result<Vec<Contributor>> {
|
19 |
| - let response = reqwasm::http::Request::get( |
20 |
| - "https://api.github.com/repos/RustLangES/rustlanges.github.io/contributors", |
21 |
| - ) |
22 |
| - .send() |
23 |
| - .await? |
24 |
| - .json::<Vec<Contributor>>() |
25 |
| - .await?; |
26 |
| - |
27 |
| - let response = join_all(response.iter().map(fetch_contributor_info)) |
28 |
| - .await |
| 51 | + let request_body = json!({ |
| 52 | + "query": GRAPH_QUERY, |
| 53 | + }); |
| 54 | + |
| 55 | + let mut headers = reqwest::header::HeaderMap::new(); |
| 56 | + |
| 57 | + headers.append( |
| 58 | + "Authorization", |
| 59 | + format!("Bearer {}", env!("GITHUB_API_TOKEN")) |
| 60 | + .parse() |
| 61 | + .unwrap(), |
| 62 | + ); |
| 63 | + |
| 64 | + let client = reqwest::ClientBuilder::new() |
| 65 | + .default_headers(headers) |
| 66 | + .build()?; |
| 67 | + |
| 68 | + let res: leptos::serde_json::Value = client |
| 69 | + .post("https://api.github.com/graphql") |
| 70 | + .send() |
| 71 | + .await? |
| 72 | + .json() |
| 73 | + .await?; |
| 74 | + |
| 75 | + let mut res = res["data"]["organization"]["repositories"]["nodes"] |
| 76 | + .as_array() |
| 77 | + .unwrap_or(&Vec::new()) |
29 | 78 | .iter()
|
30 |
| - .flat_map(|c| c.clone().ok()) |
31 |
| - .collect::<Vec<Contributor>>(); |
| 79 | + .flat_map(|repo| repo["contributors"]["nodes"].as_array().unwrap()) |
| 80 | + .map(|c| leptos::serde_json::from_value::<Contributor>(c.clone()).map_err(|e| e.into())) |
| 81 | + .collect::<Result<Vec<Contributor>>>()?; |
32 | 82 |
|
33 |
| - Ok(response) |
34 |
| -} |
| 83 | + res.sort_by_key(|a| a.contributions_collection.total_commit_contributions); |
35 | 84 |
|
36 |
| -async fn fetch_contributor_info(contributor: &Contributor) -> Result<Contributor> { |
37 |
| - Ok(reqwasm::http::Request::get(&format!( |
38 |
| - "https://api.github.com/users/{}", |
39 |
| - contributor.login |
40 |
| - )) |
41 |
| - .send() |
42 |
| - .await? |
43 |
| - .json::<Contributor>() |
44 |
| - .await |
45 |
| - .inspect(|c| log!("{c:?} - {contributor:?}")) |
46 |
| - .inspect_err(|e| error!("Error: {e:?}")) |
47 |
| - .map(|c| Contributor { |
48 |
| - contributions: contributor.contributions, |
49 |
| - ..c |
50 |
| - })?) |
| 85 | + Ok(res) |
51 | 86 | }
|
52 | 87 |
|
53 |
| -#[island] |
| 88 | +#[cfg_attr(not(debug_assertions), island)] |
| 89 | +#[cfg(not(debug_assertions))] |
54 | 90 | pub fn Contributors() -> impl IntoView {
|
55 | 91 | let contributors_results = create_local_resource(move || (), |()| fetch_contributors());
|
56 | 92 | let contributorMapper = |item: &Contributor| {
|
@@ -90,3 +126,65 @@ pub fn Contributors() -> impl IntoView {
|
90 | 126 | </section>
|
91 | 127 | }
|
92 | 128 | }
|
| 129 | + |
| 130 | +#[cfg_attr(debug_assertions, island)] |
| 131 | +#[cfg(debug_assertions)] |
| 132 | +pub fn Contributors() -> impl IntoView { |
| 133 | + let contributors = [Contributor { |
| 134 | + login: "Phosphorus-M".to_owned(), |
| 135 | + avatar_url: "https://avatars.githubusercontent.com/u/19656993?v=4".to_owned(), |
| 136 | + url: "https://github.com/Phosphorus-M".to_owned(), |
| 137 | + bio: None, |
| 138 | + twitter_username: Some("Phosphorus_M".to_owned()), |
| 139 | + location: Some("Argentina".to_owned()), |
| 140 | + contributions_collection: ContributionCollection { |
| 141 | + total_commit_contributions: 499, |
| 142 | + }, |
| 143 | + }, |
| 144 | + Contributor { |
| 145 | + login: "SergioRibera".to_owned(), |
| 146 | + avatar_url: "https://avatars.githubusercontent.com/u/56278796?u=9e3dac947b4fd3ca2f1a05024e083c64e4c69cfe&v=4".to_owned(), |
| 147 | + url: "https://github.com/SergioRibera".to_owned(), |
| 148 | + bio: Some("22yo Rustacean and Open Source lover\r\nI teach, Promote and Give Technical talks of rust with @RustLangES".to_owned()), |
| 149 | + twitter_username: Some("sergioribera_rs".to_owned()), |
| 150 | + location: Some("Santa Cruz de la Sierra, Bolivia".to_owned()), |
| 151 | + contributions_collection: ContributionCollection { |
| 152 | + total_commit_contributions: 2015 |
| 153 | + } |
| 154 | + }]; |
| 155 | + let contributorMapper = |item: &Contributor| { |
| 156 | + view! { |
| 157 | + <ContributorCard |
| 158 | + name=item.login.clone() |
| 159 | + description=item.bio.clone() |
| 160 | + link=item.url.clone() |
| 161 | + brand_src=item.avatar_url.clone() |
| 162 | + twitter=item.twitter_username.clone() |
| 163 | + location=item.location.clone() |
| 164 | + contributions=item.contributions_collection.total_commit_contributions |
| 165 | + /> |
| 166 | + } |
| 167 | + }; |
| 168 | + |
| 169 | + let contributors_view = move || { |
| 170 | + let result = contributors |
| 171 | + .iter() |
| 172 | + .map(contributorMapper) |
| 173 | + .collect::<Fragment>(); |
| 174 | + Some(result.into_view()) |
| 175 | + }; |
| 176 | + |
| 177 | + view! { |
| 178 | + <section class="bg-orange-300/30 dark:bg-transparent py-16"> |
| 179 | + <div class="flex flex-col gap-y-6 container mx-auto px-4"> |
| 180 | + <h2 class="text-3xl text-left mb-6"> |
| 181 | + <span class="font-work-sans font-light">"Nuestros "</span> |
| 182 | + <span class="font-alfa-slab text-orange-500">"Colaboradores"</span> |
| 183 | + </h2> |
| 184 | + <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-5 gap-6"> |
| 185 | + {contributors_view} |
| 186 | + </div> |
| 187 | + </div> |
| 188 | + </section> |
| 189 | + } |
| 190 | +} |
0 commit comments