//! Diffusion's views (#150, docs/diffusion.md): a repository's Diffusion //! tab (the consumers that pin it, and what it follows itself), and Admin › //! Diffusion across the hub. Each consumer shows green, amber, red, grey //! or up to date (`diffusion::Colour`). use super::{filters, lookup, Error, Page, RepoShell, Shell}; use crate::auth::Viewer; use crate::db::repos::RepoRow; use crate::diffusion::Consumer; use crate::Shared; use askama::Template; use axum::extract::{Path, State}; #[derive(Template)] #[template(path = "diffusion.html")] pub struct DiffusionPage { shell: Shell, repo: RepoShell, used_by: Vec, follows: Vec<(RepoRow, Consumer)>, /// This repository has no checks of its own: its bumps are amber. unverified: bool, } /// `GET /{owner}/{name}/diffusion`. pub async fn page( State(app): State, viewer: Viewer, Path((owner, name)): Path<(String, String)>, ) -> Result, Error> { let shell = Shell::new(&app, &format!("/{owner}/{name}/diffusion"), &viewer); let (_, row, role) = lookup(&app, &shell, &viewer, &owner, &name).await?; let used_by = crate::diffusion::consumers(&app, &row, viewer.account()).await.unwrap_or_default(); let follows = crate::diffusion::follows(&app, &row, viewer.account()).await; let unverified = crate::diffusion::unverified(&app, &row).await; Ok(Page(DiffusionPage { shell, repo: RepoShell::new(&app, &row, "diffusion").with_role(role), used_by, follows, unverified })) } #[derive(Template)] #[template(path = "admin_diffusion.html")] pub struct AdminPage { shell: Shell, upstreams: Vec<(RepoRow, Vec, bool)>, } /// `GET /admin/diffusion`: every upstream on the hub and its consumers. pub async fn admin(State(app): State, viewer: Viewer) -> Result, Error> { let shell = Shell::new(&app, "/admin/diffusion", &viewer); if !viewer.is_admin() { return Err(Error::not_found(shell)); } let upstreams = crate::diffusion::everything(&app, viewer.account()).await; Ok(Page(AdminPage { shell, upstreams })) }