diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml
index aa1eaf9..a9e7c6b 100644
--- a/.github/workflows/clippy.yml
+++ b/.github/workflows/clippy.yml
@@ -2,6 +2,7 @@ name: clippy
on:
workflow_dispatch:
pull_request:
+ branches: [main, riir]
types:
- ready_for_review
@@ -45,17 +46,9 @@ jobs:
toolchain: nightly
override: true
components: clippy
- - name: Cache .cargo and target
- uses: actions/cache@v4
- with:
- path: |
- ~/.cargo
- key: ${{ runner.os }}-cargo-leptos-${{ hashFiles('**/Cargo.lock') }}
- restore-keys: |
- ${{ runner.os }}-cargo-leptos-${{ hashFiles('**/Cargo.lock') }}
- ${{ runner.os }}-cargo-leptos
+ - uses: cargo-bins/cargo-binstall@main
- name: Install LeptosFmt
- run: cargo install leptosfmt --version 0.1.33
+ run: cargo binstall --disable-telemetry --no-confirm leptosfmt --version 0.1.33
- name: Check LeptosFmt
run: leptosfmt --check src
diff --git a/Cargo.lock b/Cargo.lock
index a3b4415..32e7c4c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -72,7 +72,7 @@ dependencies = [
"mime",
"percent-encoding",
"pin-project-lite",
- "rand 0.10.2",
+ "rand 0.10.3",
"sha1",
"smallvec",
"tokio",
@@ -2329,7 +2329,7 @@ dependencies = [
"bytes",
"getrandom 0.4.3",
"lru-slab",
- "rand 0.10.2",
+ "rand 0.10.3",
"rand_pcg",
"ring",
"rustc-hash",
@@ -2411,9 +2411,9 @@ dependencies = [
[[package]]
name = "rand"
-version = "0.10.2"
+version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
+checksum = "65c9fb96cbc91e3478eaae79a69fcd3f1ae4ad052e471fe6732fff548984b4af"
dependencies = [
"chacha20",
"getrandom 0.4.3",
@@ -2626,11 +2626,13 @@ dependencies = [
"actix-files",
"actix-web",
"console_error_panic_hook",
+ "getrandom 0.4.3",
"leptos",
"leptos-use",
"leptos_actix",
"leptos_meta",
"leptos_router",
+ "rand 0.10.3",
"reqwest",
"rustlanges-components",
"rusty-hook",
diff --git a/Cargo.toml b/Cargo.toml
index ce4ba52..83c9de7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,6 +27,8 @@ reqwest = { version = "0.13.4", features = [
rustlanges-components = { path="design-system-components", features = ["leptos"] }
leptos-use = { version = "0.19.0", features = [] }
console_error_panic_hook = { version = "0.1.7", optional = true }
+rand = "0.10.3"
+getrandom = { version = "0.4.3", features = ["wasm_js"] }
# leptos_theme = "0.1.2"
[features]
diff --git a/Makefile.toml b/Makefile.toml
index bafe7d9..87d0d28 100644
--- a/Makefile.toml
+++ b/Makefile.toml
@@ -24,14 +24,14 @@ args = ["fmt", "--all"]
[tasks.fmt-all]
script = '''
-leptosfmt .
+leptosfmt src
cargo fmt --all
cargo clippy --fix --features ssr -- -D warnings
'''
[tasks.check]
script = '''
-leptosfmt --check .
+leptosfmt --check src
cargo fmt --all --check
cargo clippy --features ssr -- -D warnings
'''
@@ -39,7 +39,7 @@ cargo clippy --features ssr -- -D warnings
[tasks.leptos-format]
install_crate = "leptosfmt"
command = "leptosfmt"
-args = ["."]
+args = ["src"]
[tasks.format]
dependencies = ["cargo-format", "leptos-format"]
diff --git a/design-system-components b/design-system-components
index 3483e05..73d2708 160000
--- a/design-system-components
+++ b/design-system-components
@@ -1 +1 @@
-Subproject commit 3483e05f8b354ef3ee01f2e8113b98b3324e9851
+Subproject commit 73d27082b5521b93d402b0e1d17264eee98c609e
diff --git a/flake.nix b/flake.nix
index 6895172..ca90778 100644
--- a/flake.nix
+++ b/flake.nix
@@ -26,6 +26,7 @@
rustToolchain
# WASM tools
+ nodejs
tailwindcss_4
wasm-bindgen-cli_0_2_126
diff --git a/src/components/contributors.rs b/src/components/contributors.rs
index d7a52eb..bf7dcd7 100644
--- a/src/components/contributors.rs
+++ b/src/components/contributors.rs
@@ -54,7 +54,7 @@ pub fn Contributors() -> impl IntoView {
- };
+ }
})
.collect_view();
@@ -74,7 +74,7 @@ pub fn Contributors() -> impl IntoView {
- {{ contributors_list }}
+ {contributors_list}
diff --git a/src/components/icons/mod.rs b/src/components/icons/mod.rs
index 0349f17..f94e075 100644
--- a/src/components/icons/mod.rs
+++ b/src/components/icons/mod.rs
@@ -5,6 +5,7 @@ mod linkedin_icon;
mod location_icon;
mod logo_rust_page;
mod next;
+mod sponsor_block;
mod telegram_icon;
mod twitter_icon;
mod web_icon;
@@ -17,6 +18,7 @@ pub use github_icon::*;
pub use linkedin_icon::*;
pub use location_icon::*;
pub use next::*;
+pub use sponsor_block::*;
pub use telegram_icon::*;
pub use twitter_icon::*;
diff --git a/src/components/icons/sponsor_block.rs b/src/components/icons/sponsor_block.rs
new file mode 100644
index 0000000..51ae05f
--- /dev/null
+++ b/src/components/icons/sponsor_block.rs
@@ -0,0 +1,34 @@
+use leptos::prelude::*;
+
+#[component]
+pub fn SponsorBlockIcon(#[prop(optional)] class: String) -> impl IntoView {
+ view! {
+
+
+
+
+
+
+
+ }
+}
diff --git a/src/components/other_communities.rs b/src/components/other_communities.rs
index 96f02cf..a760ecb 100644
--- a/src/components/other_communities.rs
+++ b/src/components/other_communities.rs
@@ -1,17 +1,113 @@
use leptos::prelude::*;
use rustlanges_components::{
avatar::Avatar,
- button::{Button, Variant as ButtonVariant},
+ button::{Variant as ButtonVariant, button_class},
card::Card,
chip::{Chip, Variant as ChipVariant},
- icons::Telegram,
+ icons::IconVariant,
input::{Filter, InputSearch},
};
type ResourceAlias = Vec
;
+// TODO(@Lemin-n): quitar el pub, please
+struct Community {
+ pub logo: &'static str,
+ pub name: &'static str,
+ pub country: &'static str,
+ pub description: &'static str,
+ pub link: Option<(&'static str, IconVariant)>,
+}
+
+const COMMUNITIES: [Community; 7] = [
+ Community {
+ name: "Rust Colombia",
+ country: "Colombia",
+ description: "Comunidad de Rust con dos sedes, en Medellín y en Bogotá",
+ logo: "https://rustlang-es.org/gen_assets/rust-colombia.webp",
+ link: Some(("https://discord.gg/krm22PuDVw", IconVariant::Discord)),
+ },
+ Community {
+ name: "Rust Venezuela",
+ country: "Venezuela duh",
+ description: "Venezuela dih",
+ logo: "https://rustlang-es.org/gen_assets/rust-venezuela.webp",
+ link: Some(("https://t.me/rustlangVE", IconVariant::Telegram)),
+ },
+ Community {
+ name: "Rust Argentina",
+ country: "Argentina claro",
+ description: "Anteriormente Rust Argentina, hoy una comunidad internacional",
+ logo: "https://rustlang-es.org/gen_assets/rust-argentina.webp",
+ link: Some(("https://t.me/rust_lang_es", IconVariant::Telegram)),
+ },
+ Community {
+ name: "Rust Ecuador",
+ country: "Ecuador",
+ description: "¡Comunidad de Rust en Ecuador!",
+ logo: "https://rustlang-es.org/gen_assets/rust_ecuador.webp",
+ link: Some(("https://t.me/rustecuador", IconVariant::Telegram)),
+ },
+ Community {
+ name: "Rust MX",
+ country: "Mexico",
+ description: "¡Comunidad de Rust en Mexico!",
+ logo: "https://rustlang-es.org/gen_assets/RustMX-min.webp",
+ link: Some(("https://t.me/RustMX", IconVariant::Telegram)),
+ },
+ Community {
+ name: "Bcn Rust",
+ country: "España",
+ description: "Comunidad de Rust en Barcelona",
+ logo: "https://rustlang-es.org/gen_assets/RustBCN.webp",
+ link: Some(("https://discord.gg/DeZKCCyMcq", IconVariant::Discord)),
+ },
+ Community {
+ name: "Rust Perú",
+ country: "Perú",
+ description: "¡Comunidad de Rust en Perú!",
+ logo: "https://rustlang-es.org/gen_assets/rust-peru.webp",
+ link: Some(("https://peru.rustlang-es.org/", IconVariant::Link)),
+ },
+];
+
#[allow(non_snake_case)]
pub fn OtherCommunities() -> impl IntoView {
+ let communities = COMMUNITIES.map(|community| {
+ let button_link = community.link.map(|(link, link_icon)| {
+ view! {
+
+ {link_icon.to_view()}
+
+ }
+ });
+
+ view! {
+
+
+
+
+
+
{community.name}
+
+
+ {community.description}
+
+
+
+
+
+ }
+ });
+
view! {
@@ -26,160 +122,7 @@ pub fn OtherCommunities() -> impl IntoView {
-
-
-
-
-
-
-
}.into_any()
- variant=ButtonVariant::Icon
- on_click=move |_| {}
- />
-
-
-
"Rust Colombia"
-
-
- "Comunidad de Rust con dos sedes, en Medellín y en Bogotá"
-
-
-
-
-
-
-
-
-
-
-
-
}.into_any()
- variant=ButtonVariant::Icon
- on_click=move |_| {}
- />
-
-
-
"Rust Venezuela"
-
-
-
-
-
-
-
-
-
-
-
-
}.into_any()
- variant=ButtonVariant::Icon
- on_click=move |_| {}
- />
-
-
-
"Rust Argentina"
-
-
- "Anteriormente Rust Argentina, hoy una comunidad internacional"
-
-
-
-
-
-
-
-
-
-
-
-
}.into_any()
- variant=ButtonVariant::Icon
- on_click=move |_| {}
- />
-
-
-
"Rust Ecuador"
-
-
- "¡Comunidad de Rust en Ecuador!"
-
-
-
-
-
-
-
-
-
-
-
-
}.into_any()
- variant=ButtonVariant::Icon
- on_click=move |_| {}
- />
-
-
-
"Rust MX"
-
-
- "¡Comunidad de Rust en Mexico!"
-
-
-
-
-
-
-
-
-
-
-
-
}.into_any()
- variant=ButtonVariant::Icon
- on_click=move |_| {}
- />
-
-
-
"Rust Perú"
-
-
- "¡Comunidad de Rust en Perú!"
-
-
-
-
-
-
+ {communities}
diff --git a/src/components/our_sponsors.rs b/src/components/our_sponsors.rs
index 70e3524..922eeba 100644
--- a/src/components/our_sponsors.rs
+++ b/src/components/our_sponsors.rs
@@ -1,6 +1,161 @@
-use leptos::prelude::*;
+use leptos::{leptos_dom::logging::console_warn, prelude::*};
-use crate::components::sponsor_block::SponsorBlock;
+use crate::components::sponsor_block::{SponsorBlock, SponsorVariant};
+
+#[derive(Default)]
+struct SponsorDef {
+ variant: SponsorVariant,
+
+ img: &'static str,
+ alt: &'static str,
+ class: &'static str,
+}
+
+enum SponsorBrick {
+ Sponsor(&'static str),
+ Empty(&'static str),
+ Space(&'static str),
+}
+
+fn sponsors() -> impl IntoView {
+ use SponsorVariant::*;
+
+ let mut sponsors_buf = vec![
+ SponsorDef {
+ variant: Black,
+ img: "/assets/sponsors/sysarmy.webp",
+ alt: "SysArmy",
+ ..Default::default()
+ },
+ SponsorDef {
+ variant: White,
+ img: "/assets/new/sponsors/testing-bolivia.png",
+ alt: "Testing Bolivia",
+ class: "mix-blend-difference",
+ },
+ SponsorDef {
+ variant: Custom("#00c39d"),
+ img: "/assets/new/sponsors/frontendcafe.png",
+ alt: "FrontendCafe",
+ class: "shadow-frontendcafe w-full h-full object-contain",
+ },
+ SponsorDef {
+ variant: Custom("#193270"),
+ img: "/assets/new/sponsors/universidad_nur.png",
+ alt: "Universidad Nur",
+ ..Default::default()
+ },
+ SponsorDef {
+ variant: Black,
+ img: "/assets/sponsors/shuttle.webp",
+ alt: "ShuttleRS",
+ class: "mix-blend-difference",
+ },
+ SponsorDef {
+ variant: Primary,
+ img: "/assets/new/sponsors/cloudflare.svg",
+ alt: "Cloudflare",
+ ..Default::default()
+ },
+ SponsorDef {
+ variant: Custom("#051024"),
+ img: "/assets/new/sponsors/crabnebula.svg",
+ alt: "Crabnebula",
+ class: "mix-blend-difference",
+ },
+ SponsorDef {
+ variant: Custom("var(--color-neutral-950)"),
+ img: "/assets/new/sponsors/tauri-logo.png",
+ alt: "Tauri",
+ ..Default::default()
+ },
+ SponsorDef {
+ variant: White,
+ img: "/assets/new/sponsors/aws.svg",
+ alt: "Amazon Web Services",
+ ..Default::default()
+ },
+ ];
+
+ // Sponsors will be "popped" from the buffer, so reverse it
+ // to get the same order as written
+ sponsors_buf.reverse();
+
+ const SPONSOR_BRICKS: usize = 26;
+
+ const BRICKS: [SponsorBrick; SPONSOR_BRICKS] = [
+ SponsorBrick::Sponsor("col-start-2 md:col-start-4"),
+ SponsorBrick::Empty(""),
+ SponsorBrick::Sponsor(""),
+ SponsorBrick::Space("hidden md:block lg:block"),
+ SponsorBrick::Space("hidden md:block lg:hidden"),
+ SponsorBrick::Sponsor(""),
+ SponsorBrick::Empty("lg:col-start-2"),
+ SponsorBrick::Space("block sm:hidden md:hidden lg:block"),
+ SponsorBrick::Sponsor("col-start-3 sm:col-start-[unset]"),
+ SponsorBrick::Space("hidden md:block lg:hidden"),
+ SponsorBrick::Empty("md:col-start-3 lg:col-start-[unset]"),
+ SponsorBrick::Sponsor("sm:col-start-3 md:col-start-[unset]"),
+ SponsorBrick::Empty(""),
+ SponsorBrick::Sponsor(""),
+ SponsorBrick::Empty("col-start-4 sm:col-start-[unset]"),
+ SponsorBrick::Sponsor(""),
+ SponsorBrick::Empty("col-start-2 sm:col-start-[unset]"),
+ SponsorBrick::Sponsor(""),
+ SponsorBrick::Empty("sm:col-start-2 md:col-start-[unset]"),
+ SponsorBrick::Space(""),
+ SponsorBrick::Sponsor("md:col-start-2 lg:col-start-3"),
+ SponsorBrick::Empty("col-start-3 md:col-start-[unset]"),
+ SponsorBrick::Space("hidden md:hidden lg:block"),
+ SponsorBrick::Empty(""),
+ SponsorBrick::Empty("hidden sm:block"),
+ SponsorBrick::Empty("hidden lg:block"),
+ ];
+
+ // Get a top-to-down zindex
+ let mut next_id = SPONSOR_BRICKS + 1;
+ let mut next_id = move || {
+ next_id -= 1;
+ next_id
+ };
+
+ let view = BRICKS.map(|b| match b {
+ SponsorBrick::Sponsor(c) if let Some(sponsor) = sponsors_buf.pop() => {
+ view! {
+
+
+
+ }
+ }
+ .into_any(),
+ // If there's no more sponsors, just show it as random empty brick.
+ // This allows to design and assign spaces to sponsors even if not enough
+ SponsorBrick::Sponsor(c) | SponsorBrick::Empty(c) => view! { }
+ .into_any(),
+ // Reserve an entire brick.
+ // Consult "What the hell???" section (below) to know more about this.
+ SponsorBrick::Space(c) => view! {
}
+ .into_any(),
+ });
+
+ if !sponsors_buf.is_empty() {
+ console_warn(&format!(
+ "{} Sponsors left. Some sponsors are not rendered: {}",
+ sponsors_buf.len(),
+ sponsors_buf
+ .into_iter()
+ .map(|s| s.alt)
+ .collect::>()
+ .join(", ")
+ ));
+ }
+
+ view
+}
#[component]
pub fn OurSponsorsSection() -> impl IntoView {
@@ -18,170 +173,19 @@ pub fn OurSponsorsSection() -> impl IntoView {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- // End mobile
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- // End mobile
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ // What the hell???
+ // R: The grid is composed from every brick section (each brick's top-connections)
+ // to align correctly in any™ position a brick is located. The cols are just an
+ // arbritrary amount of bricks that looks good in each breakpoint.
+
+ {sponsors}
diff --git a/src/components/sponsor_block.rs b/src/components/sponsor_block.rs
index b862a60..fd248f0 100644
--- a/src/components/sponsor_block.rs
+++ b/src/components/sponsor_block.rs
@@ -1,40 +1,128 @@
+use std::cell::RefCell;
+
use leptos::prelude::*;
+use rand::seq::SliceRandom;
+use wasm_bindgen::UnwrapThrowExt;
+
+use crate::components::icons::SponsorBlockIcon;
+
+const GHOST_DEBUG: bool = false;
+
+#[derive(Default, Clone, Copy, PartialEq, Eq)]
+pub enum SponsorVariant {
+ #[default]
+ Primary,
+ Secondary,
+ Tertiary,
+ Quaternary,
+ Black,
+ White,
+ Custom(&'static str),
+}
+
+impl SponsorVariant {
+ pub fn random_colored() -> Self {
+ thread_local! {
+ static COLOR_DISTRIBUTION: RefCell> = const {RefCell::new(Vec::new())};
+ }
+
+ COLOR_DISTRIBUTION.with_borrow_mut(|c| {
+ if let Some(color) = c.pop() {
+ color
+ } else {
+ *c = vec![
+ Self::Primary,
+ Self::Secondary,
+ Self::Tertiary,
+ Self::Quaternary,
+ Self::Primary,
+ Self::Secondary,
+ Self::Tertiary,
+ Self::Quaternary,
+ ];
+
+ c.shuffle(&mut rand::rng());
+
+ c.pop().expect_throw("Just filled up")
+ }
+ })
+ }
+}
#[component]
pub fn SponsorBlock(
- #[prop(into, default = "fill-primary-500")] class: &'static str,
+ #[prop(into, optional)] class: &'static str,
+ #[prop(optional)] variant: SponsorVariant,
+ #[prop(optional)] index: usize,
#[prop(optional)] children: Option,
) -> impl IntoView {
+ let (variant_custom, variant_class) = match variant {
+ SponsorVariant::Primary => (
+ None,
+ if GHOST_DEBUG {
+ "text-primary-500/5"
+ } else {
+ "text-primary-500"
+ },
+ ),
+ SponsorVariant::Secondary => (
+ None,
+ if GHOST_DEBUG {
+ "text-secondary-500/5"
+ } else {
+ "text-secondary-500"
+ },
+ ),
+ SponsorVariant::Tertiary => (
+ None,
+ if GHOST_DEBUG {
+ "text-primary-200/5"
+ } else {
+ "text-primary-200"
+ },
+ ),
+ SponsorVariant::Quaternary => (
+ None,
+ if GHOST_DEBUG {
+ "text-secondary-300/5"
+ } else {
+ "text-secondary-300"
+ },
+ ),
+ SponsorVariant::Black => (
+ None,
+ if GHOST_DEBUG {
+ "text-black/5"
+ } else {
+ "text-black"
+ },
+ ),
+ SponsorVariant::White => (
+ None,
+ if GHOST_DEBUG {
+ "text-white/5"
+ } else {
+ "text-white"
+ },
+ ),
+ SponsorVariant::Custom(s) => (Some(s), "text-(--custom-color)"),
+ };
+
view! {
-
-
{children.map(|v| v())}
-
-
-
-
-
-
-
-
- }
+
+
+ {children.map(|v| v())}
+
+
+
+ }.into_any()
}