Serve user data along with issues

This commit is contained in:
Yash Karandikar 2022-03-05 17:46:33 -06:00
parent b033e64507
commit d4539ec28b
Signed by: karx
GPG key ID: A794DA2529474BA5
3 changed files with 57 additions and 15 deletions

View file

@ -1,13 +1,13 @@
use crate::Issue; use crate::{Issue, User};
use sycamore::prelude::*; use sycamore::prelude::*;
#[component(HomeScreen<G>)] #[component(HomeScreen<G>)]
pub fn home_screen() -> View<G> { pub fn home_screen() -> View<G> {
let issues: Signal<Vec<Issue>> = Signal::new(Vec::new()); let issues: Signal<Vec<(Issue, User)>> = Signal::new(Vec::new());
if G::IS_BROWSER { if G::IS_BROWSER {
wasm_bindgen_futures::spawn_local(cloned!(issues => async move { wasm_bindgen_futures::spawn_local(cloned!(issues => async move {
let resp = reqwasm::http::Request::get("/api/issues").send().await.unwrap().text().await.unwrap(); let resp = reqwasm::http::Request::get("/api/issues").send().await.unwrap().text().await.unwrap();
let parsed: Vec<Issue> = serde_json::from_str(&resp).unwrap_or_default(); let parsed: Vec<(Issue, User)> = serde_json::from_str(&resp).unwrap_or_default();
issues.set(parsed); issues.set(parsed);
})); }));
} }
@ -15,11 +15,11 @@ pub fn home_screen() -> View<G> {
div(class="text-align-center") { div(class="text-align-center") {
Keyed(KeyedProps { Keyed(KeyedProps {
iterable: issues.handle(), iterable: issues.handle(),
template: |i| view! { template: |(i, u)| view! {
div(class="card") { div(class="card") {
h3(class="text-align-center", style="margin-bottom: 0") { (i.title) } h3(class="text-align-center", style="margin-bottom: 0") { (i.title) }
div(style="justify-content: space-between; display: flex") { div(style="justify-content: space-between; display: flex") {
div { (i.author) } div { (u.username) }
div { (i.repo) } div { (i.repo) }
} }
br {} br {}
@ -30,7 +30,7 @@ pub fn home_screen() -> View<G> {
} }
} }
}, },
key: |i| i.id, key: |(i, _)| i.id,
}) })
} }
} }

View file

@ -89,20 +89,23 @@ pub fn issue_create() -> View<G> {
#[component(IssueDetail<G>)] #[component(IssueDetail<G>)]
pub fn issue_detail(index: i64) -> View<G> { pub fn issue_detail(index: i64) -> View<G> {
let issue: Signal<Issue> = Signal::new(Issue::default()); let issue: Signal<Issue> = Signal::new(Issue::default());
let user: Signal<User> = Signal::new(User::default());
if G::IS_BROWSER { if G::IS_BROWSER {
wasm_bindgen_futures::spawn_local(cloned!(issue => async move { wasm_bindgen_futures::spawn_local(cloned!((issue, user) => async move {
let resp = reqwasm::http::Request::get(&format!("/api/issues/{}", index)).send().await.unwrap(); let resp = reqwasm::http::Request::get(&format!("/api/issues/{}", index)).send().await.unwrap();
if resp.status() == 404 { if resp.status() == 404 {
setLocation("/not_found"); // lmao setLocation("/not_found"); // lmao
} }
let text = resp.text().await.unwrap(); let text = resp.text().await.unwrap();
let parsed: Issue = serde_json::from_str(&text).unwrap(); let parsed: (Issue, User) = serde_json::from_str(&text).unwrap();
issue.set(parsed); issue.set(parsed.0);
user.set(parsed.1);
})); }));
} }
let title = create_memo(cloned!(issue => move || issue.get().title.clone())); let title = create_memo(cloned!(issue => move || issue.get().title.clone()));
let author = create_memo(cloned!(issue => move || issue.get().author.clone())); // let author = create_memo(cloned!(issue => move || issue.get().author.clone()));
let author = create_memo(cloned!(user => move || user.get().username.clone()));
let repo = create_memo(cloned!(issue => move || issue.get().repo.clone())); let repo = create_memo(cloned!(issue => move || issue.get().repo.clone()));
let desc = create_memo(cloned!(issue => move || issue.get().desc.clone())); let desc = create_memo(cloned!(issue => move || issue.get().desc.clone()));

View file

@ -7,20 +7,59 @@ use rocket::{get, post};
use std::io; use std::io;
#[get("/api/issues")] #[get("/api/issues")]
pub async fn all_issues() -> Json<Vec<Issue>> { pub async fn all_issues() -> Json<Vec<(Issue, User)>> {
Json(EXECONN.lock().await.as_ref().unwrap().all_issues().await) // Json(EXECONN.lock().await.as_ref().unwrap().all_issues().await)
let issues = EXECONN
.lock()
.await
.as_ref()
.unwrap()
.all_issues()
.await;
let mut new: Vec<(Issue, User)> = Vec::with_capacity(issues.len());
for issue in issues {
let user = EXECONN
.lock()
.await
.as_ref()
.unwrap()
.get_user_by_id(issue.author)
.await
.unwrap(); // We can safely unwrap because if issue.author is invalid then the DB is FUBAR
new.push((issue, user));
}
Json(new)
} }
#[get("/api/issues/<id>")] #[get("/api/issues/<id>")]
pub async fn get_issue(id: i64) -> Option<Json<Issue>> { pub async fn get_issue(id: i64) -> Option<Json<(Issue, User)>> {
EXECONN let issue = EXECONN
.lock() .lock()
.await .await
.as_ref() .as_ref()
.unwrap() .unwrap()
.get_issue(id) .get_issue(id)
.await;
let user_id = issue.as_ref()?.author;
let user = EXECONN
.lock()
.await .await
.map(|i| Json(i)) .as_ref()
.unwrap()
.get_user_by_id(user_id)
.await;
match (issue, user) {
(Some(a), Some(b)) => Some(Json((a, b))),
_ => None
}
} }
#[post("/api/add_issue", format = "json", data = "<user_input>")] #[post("/api/add_issue", format = "json", data = "<user_input>")]