mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-05-19 13:55:40 -04:00
feat: add contributors list and update settings page
- Introduced a new contributors.json file containing a list of contributors with their GitHub usernames. - Updated AboutSettings component to display the list of contributors dynamically. - Modified tsconfig.json to enable JSON module resolution for better imports. - Enhanced Cargo.toml to include JSON feature for reqwest. - Added a new Rust module to fetch and update the contributors list from GitHub.
This commit is contained in:
@@ -3,6 +3,7 @@ import { Ball } from "@sd/assets/images";
|
||||
import Orb from "../../components/Orb";
|
||||
import { TopBarButton } from "@sd/ui";
|
||||
import { GlobeHemisphereWest, GithubLogo, DiscordLogo } from "@phosphor-icons/react";
|
||||
import contributors from "../../contributors.json";
|
||||
|
||||
export function AboutSettings() {
|
||||
|
||||
@@ -96,11 +97,36 @@ export function AboutSettings() {
|
||||
</a>
|
||||
</motion.div>
|
||||
|
||||
{/* Contributors */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5, delay: 0.45 }}
|
||||
className="max-w-lg text-center mb-8 px-4"
|
||||
>
|
||||
<p className="text-[11px] leading-relaxed text-white/30">
|
||||
{contributors.map((c, i) => (
|
||||
<span key={c.github}>
|
||||
{i > 0 && " · "}
|
||||
<a
|
||||
href={`https://github.com/${c.github}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
title={`@${c.github}`}
|
||||
className="hover:text-white/50 transition-colors"
|
||||
>
|
||||
{c.name}
|
||||
</a>
|
||||
</span>
|
||||
))}
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
{/* License */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 0.5, delay: 0.5 }}
|
||||
transition={{ duration: 0.5, delay: 0.55 }}
|
||||
className="text-center"
|
||||
>
|
||||
<a
|
||||
|
||||
450
packages/interface/src/contributors.json
Normal file
450
packages/interface/src/contributors.json
Normal file
@@ -0,0 +1,450 @@
|
||||
[
|
||||
{
|
||||
"name": "Jamie Pine",
|
||||
"github": "jamiepine"
|
||||
},
|
||||
{
|
||||
"name": "Brendan Allan",
|
||||
"github": "Brendonovich"
|
||||
},
|
||||
{
|
||||
"name": "Oscar Beaumont",
|
||||
"github": "oscartbeaumont"
|
||||
},
|
||||
{
|
||||
"name": "Ameer Al Ashhab",
|
||||
"github": "ameer2468"
|
||||
},
|
||||
{
|
||||
"name": "Arnab Chakraborty",
|
||||
"github": "Rocky43007"
|
||||
},
|
||||
{
|
||||
"name": "Ericson \"Fogo\" Soares",
|
||||
"github": "fogodev"
|
||||
},
|
||||
{
|
||||
"name": "nikec",
|
||||
"github": "niikeec"
|
||||
},
|
||||
{
|
||||
"name": "Vítor Vasconcellos",
|
||||
"github": "HeavenVolkoff"
|
||||
},
|
||||
{
|
||||
"name": "maxichrome",
|
||||
"github": "maxichrome"
|
||||
},
|
||||
{
|
||||
"name": "jake",
|
||||
"github": "brxken128"
|
||||
},
|
||||
{
|
||||
"name": "Utku",
|
||||
"github": "utkubakir"
|
||||
},
|
||||
{
|
||||
"name": "Lynx",
|
||||
"github": "iLynxcat"
|
||||
},
|
||||
{
|
||||
"name": "Matthew Yung",
|
||||
"github": "myung03"
|
||||
},
|
||||
{
|
||||
"name": "Julian Braha",
|
||||
"github": "julianbraha"
|
||||
},
|
||||
{
|
||||
"name": "Gedeon",
|
||||
"github": "gedeondoescode"
|
||||
},
|
||||
{
|
||||
"name": "William Stoneham",
|
||||
"github": "RockBacon9922"
|
||||
},
|
||||
{
|
||||
"name": "Haris",
|
||||
"github": "xPolar"
|
||||
},
|
||||
{
|
||||
"name": "Artsiom Voitas",
|
||||
"github": "artsiom-voitas"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin",
|
||||
"github": "benja"
|
||||
},
|
||||
{
|
||||
"name": "Consoli",
|
||||
"github": "matheus-consoli"
|
||||
},
|
||||
{
|
||||
"name": "Andre",
|
||||
"github": "CreatingBytes"
|
||||
},
|
||||
{
|
||||
"name": "Aditya",
|
||||
"github": "Raghav-45"
|
||||
},
|
||||
{
|
||||
"name": "pr",
|
||||
"github": "PineappleRind"
|
||||
},
|
||||
{
|
||||
"name": "Stella",
|
||||
"github": "KodingDev"
|
||||
},
|
||||
{
|
||||
"name": "voletro",
|
||||
"github": "voletro"
|
||||
},
|
||||
{
|
||||
"name": "Lars Gyrup Brink Nielsen",
|
||||
"github": "LayZeeDK"
|
||||
},
|
||||
{
|
||||
"name": "Olen Latham",
|
||||
"github": "PyRo1121"
|
||||
},
|
||||
{
|
||||
"name": "Starbird",
|
||||
"github": "StarbirdTech"
|
||||
},
|
||||
{
|
||||
"name": "Harry Hopkinson",
|
||||
"github": "Harry-Hopkinson"
|
||||
},
|
||||
{
|
||||
"name": "Abhinav A",
|
||||
"github": "abhnva"
|
||||
},
|
||||
{
|
||||
"name": "wany-oh",
|
||||
"github": "wany-oh"
|
||||
},
|
||||
{
|
||||
"name": "Zakher Masri",
|
||||
"github": "zaaakher"
|
||||
},
|
||||
{
|
||||
"name": "Yukeey",
|
||||
"github": "Yukeey07"
|
||||
},
|
||||
{
|
||||
"name": "Md. Fahim Bin Amin",
|
||||
"github": "FahimFBA"
|
||||
},
|
||||
{
|
||||
"name": "Baran Mordoğan",
|
||||
"github": "okunamayanad"
|
||||
},
|
||||
{
|
||||
"name": "Na Risong",
|
||||
"github": "HeavySnowJakarta"
|
||||
},
|
||||
{
|
||||
"name": "Sreecharan",
|
||||
"github": "sr2echa"
|
||||
},
|
||||
{
|
||||
"name": "matt morris",
|
||||
"github": "mmattbtw"
|
||||
},
|
||||
{
|
||||
"name": "Jules Guesnon",
|
||||
"github": "JulesGuesnon"
|
||||
},
|
||||
{
|
||||
"name": "Madison Konig",
|
||||
"github": "MadisonKonig"
|
||||
},
|
||||
{
|
||||
"name": "Omar Hamad",
|
||||
"github": "etahamad"
|
||||
},
|
||||
{
|
||||
"name": "he1d1",
|
||||
"github": "he1d1"
|
||||
},
|
||||
{
|
||||
"name": "Ned Park",
|
||||
"github": "ned-park"
|
||||
},
|
||||
{
|
||||
"name": "Carter",
|
||||
"github": "berbaroovez"
|
||||
},
|
||||
{
|
||||
"name": "Tom Heaton",
|
||||
"github": "tomheaton"
|
||||
},
|
||||
{
|
||||
"name": "Tim Havlicek",
|
||||
"github": "luckydye"
|
||||
},
|
||||
{
|
||||
"name": "Tilo",
|
||||
"github": "Tilo-K"
|
||||
},
|
||||
{
|
||||
"name": "Sinan Gençoğlu",
|
||||
"github": "SinanGncgl"
|
||||
},
|
||||
{
|
||||
"name": "Michelangelo Guerra",
|
||||
"github": "XSPGMike"
|
||||
},
|
||||
{
|
||||
"name": "Marques Scripps",
|
||||
"github": "MarquesCoding"
|
||||
},
|
||||
{
|
||||
"name": "Abe",
|
||||
"github": "FastestMolasses"
|
||||
},
|
||||
{
|
||||
"name": "Carter",
|
||||
"github": "Carterpersall"
|
||||
},
|
||||
{
|
||||
"name": "Vikram Srinivas",
|
||||
"github": "vikram2009"
|
||||
},
|
||||
{
|
||||
"name": "Twan L",
|
||||
"github": "TwanLuttik"
|
||||
},
|
||||
{
|
||||
"name": "Syntax",
|
||||
"github": "TheUltDev"
|
||||
},
|
||||
{
|
||||
"name": "Takshil Mistry",
|
||||
"github": "daUnknownCoder"
|
||||
},
|
||||
{
|
||||
"name": "Sarah Bobbe",
|
||||
"github": "SBobbe"
|
||||
},
|
||||
{
|
||||
"name": "Ramprakash",
|
||||
"github": "CodePurble"
|
||||
},
|
||||
{
|
||||
"name": "Johan Sandgren",
|
||||
"github": "Qrutz"
|
||||
},
|
||||
{
|
||||
"name": "Phedona",
|
||||
"github": "Phedona"
|
||||
},
|
||||
{
|
||||
"name": "Percy Ma",
|
||||
"github": "kecrily"
|
||||
},
|
||||
{
|
||||
"name": "Param Birje",
|
||||
"github": "ParamBirje"
|
||||
},
|
||||
{
|
||||
"name": "Niklas Wojtkowiak",
|
||||
"github": "0xnim"
|
||||
},
|
||||
{
|
||||
"name": "Nicolás Fishman",
|
||||
"github": "nicofishman"
|
||||
},
|
||||
{
|
||||
"name": "Mykola",
|
||||
"github": "handicraftsman"
|
||||
},
|
||||
{
|
||||
"name": "Nicholas",
|
||||
"github": "alsonick"
|
||||
},
|
||||
{
|
||||
"name": "0xBA5E64",
|
||||
"github": "0xBA5E64"
|
||||
},
|
||||
{
|
||||
"name": "Whisht",
|
||||
"github": "Whisht"
|
||||
},
|
||||
{
|
||||
"name": "Yousef Abu-Salah",
|
||||
"github": "ykabusalah"
|
||||
},
|
||||
{
|
||||
"name": "andriizaiets",
|
||||
"github": "andriizaiets"
|
||||
},
|
||||
{
|
||||
"name": "devqore",
|
||||
"github": "devqore"
|
||||
},
|
||||
{
|
||||
"name": "erikpodusel",
|
||||
"github": "erikpodusel"
|
||||
},
|
||||
{
|
||||
"name": "David",
|
||||
"github": "fivestones"
|
||||
},
|
||||
{
|
||||
"name": "Christopher",
|
||||
"github": "itschip"
|
||||
},
|
||||
{
|
||||
"name": "jenniferdewan",
|
||||
"github": "jenniferdewan"
|
||||
},
|
||||
{
|
||||
"name": "leo",
|
||||
"github": "greendoescode"
|
||||
},
|
||||
{
|
||||
"name": "lzt1008",
|
||||
"github": "lzt1008"
|
||||
},
|
||||
{
|
||||
"name": "mark-strudwick",
|
||||
"github": "mark-strudwick"
|
||||
},
|
||||
{
|
||||
"name": "markrieder",
|
||||
"github": "markrieder"
|
||||
},
|
||||
{
|
||||
"name": "mooy",
|
||||
"github": "mooyg"
|
||||
},
|
||||
{
|
||||
"name": "S.L",
|
||||
"github": "slvnlrt"
|
||||
},
|
||||
{
|
||||
"name": "AhmedKaram",
|
||||
"github": "Adamkaram"
|
||||
},
|
||||
{
|
||||
"name": "Alex",
|
||||
"github": "misxki"
|
||||
},
|
||||
{
|
||||
"name": "Allie",
|
||||
"github": "ChildishGiant"
|
||||
},
|
||||
{
|
||||
"name": "Anthony Morris",
|
||||
"github": "amorriscode"
|
||||
},
|
||||
{
|
||||
"name": "BI3TKL",
|
||||
"github": "Nightingale0504"
|
||||
},
|
||||
{
|
||||
"name": "briamoe",
|
||||
"github": "briamoe"
|
||||
},
|
||||
{
|
||||
"name": "Bryan",
|
||||
"github": "CodeWithBryan"
|
||||
},
|
||||
{
|
||||
"name": "Cavell Blood",
|
||||
"github": "cavellblood"
|
||||
},
|
||||
{
|
||||
"name": "Cedric ",
|
||||
"github": "ceddy4395"
|
||||
},
|
||||
{
|
||||
"name": "Christo Todorov",
|
||||
"github": "chroxify"
|
||||
},
|
||||
{
|
||||
"name": "Colin Griffin",
|
||||
"github": "krumware"
|
||||
},
|
||||
{
|
||||
"name": "Conrad Crawford",
|
||||
"github": "cnrad"
|
||||
},
|
||||
{
|
||||
"name": "Eric Wyne",
|
||||
"github": "ecwyne"
|
||||
},
|
||||
{
|
||||
"name": "HardikBandhiya",
|
||||
"github": "BandhiyaHardik"
|
||||
},
|
||||
{
|
||||
"name": "Ilkka Poutanen",
|
||||
"github": "ilkka"
|
||||
},
|
||||
{
|
||||
"name": "Hesham Abourgheba",
|
||||
"github": "IllusionMan1212"
|
||||
},
|
||||
{
|
||||
"name": "Jeremy Möglich",
|
||||
"github": "JeremyMoeglich"
|
||||
},
|
||||
{
|
||||
"name": "Jesse Rodrigo",
|
||||
"github": "JSSRDRG"
|
||||
},
|
||||
{
|
||||
"name": "John Xu",
|
||||
"github": "dyxushuai"
|
||||
},
|
||||
{
|
||||
"name": "Jx",
|
||||
"github": "JxJxxJxJ"
|
||||
},
|
||||
{
|
||||
"name": "erian",
|
||||
"github": "oopserian"
|
||||
},
|
||||
{
|
||||
"name": "Leora",
|
||||
"github": "Kuuchuu"
|
||||
},
|
||||
{
|
||||
"name": "Liam Brewer",
|
||||
"github": "liambrewer"
|
||||
},
|
||||
{
|
||||
"name": "Lkhsss",
|
||||
"github": "Lkhsss"
|
||||
},
|
||||
{
|
||||
"name": "Majal",
|
||||
"github": "majal"
|
||||
},
|
||||
{
|
||||
"name": "Marc Espin",
|
||||
"github": "marc2332"
|
||||
},
|
||||
{
|
||||
"name": "Matteo Galiazzo",
|
||||
"github": "gekoxyz"
|
||||
},
|
||||
{
|
||||
"name": "Matthias Berchtold",
|
||||
"github": "iammatthi"
|
||||
},
|
||||
{
|
||||
"name": "Mohammed Bajuaifer",
|
||||
"github": "MohammedBajuaifer"
|
||||
},
|
||||
{
|
||||
"name": "Naman Garg",
|
||||
"github": "namanlp"
|
||||
},
|
||||
{
|
||||
"name": "Nebhay",
|
||||
"github": "Nebhay"
|
||||
}
|
||||
]
|
||||
@@ -8,6 +8,7 @@
|
||||
"module": "ESNext",
|
||||
"target": "ES2022",
|
||||
"moduleResolution": "bundler",
|
||||
"resolveJsonModule": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": ["./src/*"]
|
||||
|
||||
@@ -9,7 +9,7 @@ anyhow = "1"
|
||||
flate2 = "1.0"
|
||||
mustache = "0.9"
|
||||
owo-colors = "4"
|
||||
reqwest = { version = "0.12", features = ["blocking", "rustls-tls"], default-features = false }
|
||||
reqwest = { version = "0.12", features = ["blocking", "json", "rustls-tls"], default-features = false }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
tar = "0.4"
|
||||
|
||||
156
xtask/src/contributors.rs
Normal file
156
xtask/src/contributors.rs
Normal file
@@ -0,0 +1,156 @@
|
||||
use anyhow::{Context, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::Path;
|
||||
|
||||
const REPO: &str = "spacedriveapp/spacedrive";
|
||||
const OUTPUT_PATH: &str = "packages/interface/src/contributors.json";
|
||||
const EXCLUDED_LOGINS: &[&str] = &["cursoragent"];
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct GitHubContributor {
|
||||
login: String,
|
||||
#[serde(rename = "type")]
|
||||
account_type: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct GitHubUser {
|
||||
name: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Contributor {
|
||||
name: String,
|
||||
github: String,
|
||||
}
|
||||
|
||||
/// Try to get a GitHub token from the environment or `gh` CLI
|
||||
fn get_github_token() -> Option<String> {
|
||||
if let Ok(token) = std::env::var("GITHUB_TOKEN") {
|
||||
return Some(token);
|
||||
}
|
||||
|
||||
std::process::Command::new("gh")
|
||||
.args(["auth", "token"])
|
||||
.output()
|
||||
.ok()
|
||||
.and_then(|o| {
|
||||
if o.status.success() {
|
||||
String::from_utf8(o.stdout).ok().map(|s| s.trim().to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn github_get(
|
||||
client: &reqwest::blocking::Client,
|
||||
url: &str,
|
||||
token: Option<&str>,
|
||||
) -> reqwest::blocking::RequestBuilder {
|
||||
let mut req = client.get(url);
|
||||
if let Some(token) = token {
|
||||
req = req.bearer_auth(token);
|
||||
}
|
||||
req
|
||||
}
|
||||
|
||||
pub fn update(project_root: &Path) -> Result<()> {
|
||||
println!("Fetching contributors from GitHub...");
|
||||
|
||||
let token = get_github_token();
|
||||
if token.is_some() {
|
||||
println!(" using authenticated requests");
|
||||
} else {
|
||||
println!(" no token found, using unauthenticated requests (may hit rate limits)");
|
||||
println!(" tip: install `gh` CLI and run `gh auth login` for higher limits");
|
||||
}
|
||||
|
||||
let client = reqwest::blocking::Client::builder()
|
||||
.user_agent("spacedrive-xtask")
|
||||
.build()
|
||||
.context("Failed to build HTTP client")?;
|
||||
|
||||
// Paginate through all contributors
|
||||
let mut all_contributors = Vec::new();
|
||||
let mut page = 1u32;
|
||||
|
||||
loop {
|
||||
let url = format!(
|
||||
"https://api.github.com/repos/{}/contributors?per_page=100&page={}",
|
||||
REPO, page
|
||||
);
|
||||
|
||||
let resp: Vec<GitHubContributor> = github_get(&client, &url, token.as_deref())
|
||||
.send()
|
||||
.context("Failed to fetch contributors")?
|
||||
.json()
|
||||
.context("Failed to parse contributors response")?;
|
||||
|
||||
if resp.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
||||
all_contributors.extend(resp);
|
||||
page += 1;
|
||||
}
|
||||
|
||||
// Filter out bots and excluded accounts
|
||||
let humans: Vec<_> = all_contributors
|
||||
.iter()
|
||||
.filter(|c| c.account_type == "User" && !EXCLUDED_LOGINS.contains(&c.login.as_str()))
|
||||
.collect();
|
||||
|
||||
println!("Found {} contributors, resolving names...", humans.len());
|
||||
|
||||
let mut contributors = Vec::new();
|
||||
|
||||
for (i, contributor) in humans.iter().enumerate() {
|
||||
let name = match resolve_name(&client, &contributor.login, token.as_deref()) {
|
||||
Ok(Some(n)) => n,
|
||||
_ => contributor.login.clone(),
|
||||
};
|
||||
|
||||
contributors.push(Contributor {
|
||||
name,
|
||||
github: contributor.login.clone(),
|
||||
});
|
||||
|
||||
// Progress indicator every 25 users
|
||||
if (i + 1) % 25 == 0 {
|
||||
println!(" resolved {}/{}", i + 1, humans.len());
|
||||
}
|
||||
}
|
||||
|
||||
println!(" resolved {}/{}", contributors.len(), humans.len());
|
||||
|
||||
let output_path = project_root.join(OUTPUT_PATH);
|
||||
let json = serde_json::to_string_pretty(&contributors)
|
||||
.context("Failed to serialize contributors")?;
|
||||
|
||||
std::fs::write(&output_path, format!("{}\n", json))
|
||||
.context("Failed to write contributors.json")?;
|
||||
|
||||
println!(
|
||||
"Wrote {} contributors to {}",
|
||||
contributors.len(),
|
||||
OUTPUT_PATH
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn resolve_name(
|
||||
client: &reqwest::blocking::Client,
|
||||
login: &str,
|
||||
token: Option<&str>,
|
||||
) -> Result<Option<String>> {
|
||||
let url = format!("https://api.github.com/users/{}", login);
|
||||
let user: GitHubUser = github_get(client, &url, token)
|
||||
.send()
|
||||
.context("Failed to fetch user")?
|
||||
.json()
|
||||
.context("Failed to parse user response")?;
|
||||
|
||||
Ok(user.name.filter(|n: &String| !n.is_empty()))
|
||||
}
|
||||
@@ -25,6 +25,7 @@
|
||||
//! - No external tools required (except cargo/rustup)
|
||||
|
||||
mod config;
|
||||
mod contributors;
|
||||
mod native_deps;
|
||||
mod system;
|
||||
mod test_core;
|
||||
@@ -67,6 +68,7 @@ fn main() -> Result<()> {
|
||||
eprintln!(" build-ios Build sd-ios-core XCFramework for iOS devices and simulator");
|
||||
eprintln!(" build-mobile Build sd-mobile-core for React Native iOS/Android");
|
||||
eprintln!(" test-core Run all core integration tests with progress tracking");
|
||||
eprintln!(" update-contributors Fetch contributors from GitHub and update contributors.json");
|
||||
eprintln!();
|
||||
eprintln!("Examples:");
|
||||
eprintln!(" cargo xtask setup # First time setup");
|
||||
@@ -88,6 +90,10 @@ fn main() -> Result<()> {
|
||||
.unwrap_or(false);
|
||||
test_core_command(verbose)?;
|
||||
}
|
||||
"update-contributors" => {
|
||||
let project_root = find_workspace_root()?;
|
||||
contributors::update(&project_root)?;
|
||||
}
|
||||
_ => {
|
||||
eprintln!("Unknown command: {}", args[1]);
|
||||
eprintln!("Run 'cargo xtask' for usage information.");
|
||||
|
||||
Reference in New Issue
Block a user