122 lines
3.3 KiB
Rust
122 lines
3.3 KiB
Rust
use crate::effects::star_field;
|
|
use crate::slide::Slide;
|
|
use crate::slide_show_config::Context;
|
|
use crate::text_drawer::{Justified, TextConfigBuilder};
|
|
use crate::utils::{draw_rectangle_with_border, screen_center};
|
|
use macroquad::color::{BLACK, DARKGREEN, GREEN};
|
|
use macroquad::math::Vec2;
|
|
use macroquad::prelude::{clear_background, screen_height, screen_width};
|
|
use rand::prelude::IndexedRandom;
|
|
use rand::rng;
|
|
use serde::Deserialize;
|
|
use std::f32::consts::PI;
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
#[allow(dead_code)]
|
|
struct GiteaRepo {
|
|
pub id: u64,
|
|
pub name: String,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
#[allow(dead_code)]
|
|
struct GiteaResponse {
|
|
pub ok: bool,
|
|
pub data: Vec<GiteaRepo>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct FloatingText {
|
|
pos: Vec2,
|
|
vel: Vec2,
|
|
text: String,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Projects {
|
|
repos: Vec<FloatingText>,
|
|
}
|
|
|
|
impl Projects {
|
|
pub fn new() -> Box<Self> {
|
|
let resp: GiteaResponse =
|
|
reqwest::blocking::get("https://git.ahines.net/api/v1/repos/search")
|
|
.unwrap()
|
|
.json()
|
|
.unwrap();
|
|
|
|
let repos: Vec<FloatingText> = resp
|
|
.data
|
|
.into_iter()
|
|
.filter_map(|r| {
|
|
if !r.name.starts_with("_") {
|
|
Some(FloatingText {
|
|
pos: Default::default(),
|
|
vel: Default::default(),
|
|
text: r.name,
|
|
})
|
|
} else {
|
|
None
|
|
}
|
|
})
|
|
.collect();
|
|
|
|
Box::new(Self { repos })
|
|
}
|
|
}
|
|
|
|
impl Slide for Projects {
|
|
fn display(&mut self, ctx: &Context<'_>) {
|
|
clear_background(BLACK);
|
|
star_field();
|
|
|
|
let text_cfg = TextConfigBuilder::new(ctx.slide_show_theme.body_config.clone())
|
|
.font_size(75)
|
|
.justification(Justified::Center)
|
|
.build();
|
|
|
|
for repo in &mut self.repos {
|
|
if repo.pos.x <= 0.0
|
|
|| repo.pos.y <= 0.0
|
|
|| repo.pos.x > screen_width()
|
|
|| repo.pos.y > screen_height()
|
|
{
|
|
repo.pos = screen_center();
|
|
let vel: f32 = rand::random_range(1.0..1.5);
|
|
let angle: f32 = rand::random_range(0.0..2.0 * PI);
|
|
|
|
repo.vel = Vec2::new(vel, 0.0).rotate(Vec2::from(angle.sin_cos()));
|
|
|
|
repo.vel = Vec2::new(rand::random_range(0.1..1.5), rand::random_range(0.1..1.5));
|
|
|
|
repo.vel.x *= [-1.0, 1.0].choose(&mut rng()).unwrap();
|
|
repo.vel.y *= [-1.0, 1.0].choose(&mut rng()).unwrap();
|
|
}
|
|
|
|
text_cfg.draw_text(&repo.text, repo.pos);
|
|
|
|
repo.pos += repo.vel
|
|
}
|
|
let dim = ctx
|
|
.slide_show_theme
|
|
.heading_config
|
|
.measure_text("https://git.ahines.net");
|
|
|
|
let background_rectangle_size = Vec2::new(dim.width * 1.2, dim.height * 1.2);
|
|
let pos =
|
|
screen_center() - background_rectangle_size * 0.5 - Vec2::new(0.0, dim.offset_y * 0.5);
|
|
|
|
draw_rectangle_with_border(
|
|
pos,
|
|
background_rectangle_size,
|
|
background_rectangle_size.x * 0.01,
|
|
GREEN,
|
|
DARKGREEN,
|
|
);
|
|
|
|
ctx.slide_show_theme
|
|
.heading_config
|
|
.draw_text("https://git.ahines.net", screen_center());
|
|
}
|
|
}
|