diff --git a/src/pages/chart/home.rs b/src/pages/chart/home.rs new file mode 100644 index 0000000..87bb1b3 --- /dev/null +++ b/src/pages/chart/home.rs @@ -0,0 +1,131 @@ +/* + * ForgeFlux StarChart - A federated software forge spider + * Copyright © 2022 Aravinth Manivannan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +use actix_web::http::{self, header::ContentType}; +use actix_web::{HttpResponse, Responder}; +use actix_web_codegen_const_routes::{get, post}; +use log::info; +use serde::{Deserialize, Serialize}; +use std::cell::RefCell; +use tera::Context; +use url::Url; + +use db_core::prelude::*; + +use crate::errors::ServiceResult; +use crate::pages::errors::*; +use crate::settings::Settings; +use crate::verify::TXTChallenge; +use crate::*; + +pub use crate::pages::*; + +pub const TITLE: &str = "Explore"; +pub const HOME: TemplateFile = TemplateFile::new("home_page", "pages/chart/index.html"); +pub const REPO_INFO: TemplateFile = + TemplateFile::new("repo_info", "pages/chart/components/repo_info.html"); + +pub struct HomePage { + ctx: RefCell, +} + +impl CtxError for HomePage { + fn with_error(&self, e: &ReadableError) -> String { + self.ctx.borrow_mut().insert(ERROR_KEY, e); + self.render() + } +} + +#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize)] +pub struct HomePagePayload { + pub repos: Vec, + pub next_page: String, + pub prev_page: String, +} + +impl HomePage { + fn new(settings: &Settings, payload: &HomePagePayload) -> Self { + let ctx = RefCell::new(ctx(settings)); + ctx.borrow_mut().insert(TITLE_KEY, TITLE); + ctx.borrow_mut().insert(PAYLOAD_KEY, payload); + Self { ctx } + } + + pub fn render(&self) -> String { + TEMPLATES.render(HOME.name, &self.ctx.borrow()).unwrap() + } + + pub fn page(s: &Settings, payload: &HomePagePayload) -> String { + let p = Self::new(s, payload); + p.render() + } +} + +pub fn services(cfg: &mut web::ServiceConfig) { + cfg.service(home); +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct Page { + pub page: u32, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct OptionalPage { + pub page: Option, +} + +impl From for Page { + fn from(o: OptionalPage) -> Self { + match o.page { + Some(page) => Self { page }, + None => Page { page: 2 }, + } + } +} + +#[get(path = "PAGES.home")] +pub async fn home( + q: web::Query, + ctx: WebCtx, + db: WebDB, +) -> PageResult { + let q = q.into_inner(); + async fn _home(ctx: &ArcCtx, db: &BoxDB, p: &Page) -> ServiceResult> { + const LIMIT: u32 = 10; + let responses = db.get_all_repositories(p.page, LIMIT).await?; + Ok(responses) + } + let q: Page = q.into(); + + let repos = _home(&ctx, &db, &q).await.map_err(|e| { + let x = HomePagePayload::default(); + PageError::new(HomePage::new(&ctx.settings, &x), e) + })?; + + let prev = if q.page == 2 { 1 } else { q.page - 1 }; + + let payload = HomePagePayload { + repos, + next_page: PAGES.home_next(q.page + 1), + prev_page: PAGES.home_next(prev), + }; + let page = HomePage::page(&ctx.settings, &payload); + + let html = ContentType::html(); + Ok(HttpResponse::Ok().content_type(html).body(page)) +} diff --git a/src/pages/chart/mod.rs b/src/pages/chart/mod.rs new file mode 100644 index 0000000..7e1a82d --- /dev/null +++ b/src/pages/chart/mod.rs @@ -0,0 +1,32 @@ +/* + * ForgeFlux StarChart - A federated software forge spider + * Copyright © 2022 Aravinth Manivannan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +pub mod home; +pub use home::HOME; +pub use home::REPO_INFO; + +pub use super::{ctx, TemplateFile, ERROR_KEY, PAGES, PAYLOAD_KEY, TITLE_KEY}; + +pub fn register_templates(t: &mut tera::Tera) { + HOME.register(t).expect(HOME.name); + REPO_INFO.register(t).expect(REPO_INFO.name); +} + +pub fn services(cfg: &mut actix_web::web::ServiceConfig) { + home::services(cfg); +} diff --git a/src/pages/mod.rs b/src/pages/mod.rs index f87e36f..9a771bc 100644 --- a/src/pages/mod.rs +++ b/src/pages/mod.rs @@ -26,6 +26,7 @@ use crate::static_assets::ASSETS; use crate::{GIT_COMMIT_HASH, VERSION}; pub mod auth; +pub mod chart; mod errors; pub mod routes; @@ -70,6 +71,7 @@ lazy_static! { } errors::register_templates(&mut tera); auth::register_templates(&mut tera); + chart::register_templates(&mut tera); tera.autoescape_on(vec![".html", ".sql"]); //auth::register_templates(&mut tera); //gists::register_templates(&mut tera); @@ -122,6 +124,7 @@ impl<'a> Footer<'a> { pub fn services(cfg: &mut web::ServiceConfig) { auth::services(cfg); + chart::services(cfg); } #[cfg(test)] @@ -140,6 +143,7 @@ mod tests { PUB_NAV, auth::AUTH_CHALLENGE, auth::AUTH_ADD, + chart::HOME, // auth::AUTH_BASE, // auth::login::LOGIN, // auth::register::REGISTER, diff --git a/src/pages/routes.rs b/src/pages/routes.rs index 49403fe..392183f 100644 --- a/src/pages/routes.rs +++ b/src/pages/routes.rs @@ -36,6 +36,10 @@ impl Pages { let auth = Auth::new(); Pages { home, auth } } + + pub fn home_next(&self, page: u32) -> String { + format!("{}?page={page}", self.home) + } } #[derive(Serialize)] diff --git a/static/cache/css/main.css b/static/cache/css/main.css index bd0315d..6e4d75e 100644 --- a/static/cache/css/main.css +++ b/static/cache/css/main.css @@ -253,3 +253,32 @@ button { border-radius: none; border: none; } + + + + +/* Inline #1 | http://localhost:7000/ */ + +.repository__container { + width: 100%; + margin: 20px auto; + display: flex; + flex-direction: column; + justify-content: center; + border-bottom: 1px grey dotted; +} + +.repository__tags { +} + +.repository_tags > a { + background: lightgreen; +} + +.repository__tags > a { + background: lightgreen; + margin: 15px 2px; + padding: 1px; + border-radius: 5px; +} + diff --git a/templates/components/nav/pub.html b/templates/components/nav/pub.html index 97dc15c..872dccc 100644 --- a/templates/components/nav/pub.html +++ b/templates/components/nav/pub.html @@ -13,6 +13,10 @@