adds reactive status to search results

This commit is contained in:
Joe Ardent 2024-01-01 12:19:04 -08:00
parent c4976a3efc
commit 8708271d9d
5 changed files with 59 additions and 17 deletions

View file

@ -40,8 +40,8 @@ pub async fn app(db_pool: sqlx::SqlitePool) -> IntoMakeService<axum::Router> {
use signup::{get_create_user, get_signup_success, post_create_user}; use signup::{get_create_user, get_signup_success, post_create_user};
use tower_http::services::ServeDir; use tower_http::services::ServeDir;
use watches::handlers::{ use watches::handlers::{
get_add_new_watch, get_search_watch, get_watch, get_watches, post_add_new_watch, get_add_new_watch, get_search_watch, get_watch, get_watch_status, get_watches,
post_add_watch_quest, post_add_new_watch, post_add_watch_quest,
}; };
let auth_layer = { let auth_layer = {
@ -67,6 +67,7 @@ pub async fn app(db_pool: sqlx::SqlitePool) -> IntoMakeService<axum::Router> {
.route("/watches", get(get_watches)) .route("/watches", get(get_watches))
.route("/watch", get(get_watch)) .route("/watch", get(get_watch))
.route("/watch/:id", get(get_watch)) .route("/watch/:id", get(get_watch))
.route("/watch/status/:id", get(get_watch_status))
.route("/search", get(get_search_watch)) .route("/search", get(get_search_watch))
.route("/add", get(get_add_new_watch).post(post_add_new_watch)) .route("/add", get(get_add_new_watch).post(post_add_new_watch))
.route( .route(

View file

@ -78,6 +78,11 @@ pub struct SearchQuery {
pub year: Option<i64>, pub year: Option<i64>,
} }
#[derive(Debug, Default, Clone, Deserialize, PartialEq, Eq)]
pub struct StatusQuery {
pub public: bool,
}
// kinda the main form? // kinda the main form?
#[derive(Debug, Default, Deserialize, PartialEq, Eq)] #[derive(Debug, Default, Deserialize, PartialEq, Eq)]
pub struct PostAddNewWatch { pub struct PostAddNewWatch {
@ -129,8 +134,8 @@ pub async fn post_add_new_watch(
let watch_id = add_new_watch_impl(&pool, &watch).await?; let watch_id = add_new_watch_impl(&pool, &watch).await?;
let quest = WatchQuest { let quest = WatchQuest {
user: user.id, user: user.id,
is_public: !form.private, public: !form.private,
already_watched: form.watched_already, watched: form.watched_already,
watch: watch_id, watch: watch_id,
}; };
add_watch_quest_impl(&pool, &quest) add_watch_quest_impl(&pool, &quest)
@ -172,8 +177,8 @@ pub async fn post_add_watch_quest(
let quest = WatchQuest { let quest = WatchQuest {
user: user.id, user: user.id,
watch: Julid::from_string(&form.watch).unwrap(), watch: Julid::from_string(&form.watch).unwrap(),
is_public: form.public, public: form.public,
already_watched: form.watched_already, watched: form.watched_already,
}; };
add_watch_quest_impl(&pool, &quest) add_watch_quest_impl(&pool, &quest)
.await .await
@ -193,8 +198,8 @@ pub async fn add_watch_quest_impl(pool: &SqlitePool, quest: &WatchQuest) -> Resu
query(ADD_WATCH_QUEST_QUERY) query(ADD_WATCH_QUEST_QUERY)
.bind(quest.user) .bind(quest.user)
.bind(quest.watch) .bind(quest.watch)
.bind(quest.is_public) .bind(quest.public)
.bind(quest.already_watched) .bind(quest.watched)
.execute(pool) .execute(pool)
.await .await
.map_err(|err| { .map_err(|err| {
@ -275,3 +280,41 @@ pub async fn get_search_watch(
search: search_string, search: search_string,
} }
} }
pub async fn get_watch_status(
auth: AuthSession,
State(pool): State<SqlitePool>,
query: Query<StatusQuery>,
Path(watch): Path<String>,
) -> Result<impl IntoResponse, ()> {
if let Some(user) = auth.user {
let watch = Julid::from_string(&watch).unwrap();
let public = query.public;
let quest: Option<WatchQuest> =
query_as("select * from watch_quests where user = ? and watch = ? and public = ?")
.bind(user.id)
.bind(watch)
.bind(public)
.fetch_optional(&pool)
.await
.map_err(|e| {
tracing::error!("Got error from checking watch status: {e:?}");
})?;
match quest {
Some(_) => Ok("&#10003;".into_response()),
_ => Ok(format!(
"<form id=\"add-watch-{watch}\">
<input type=\"hidden\" name=\"watch\" value=\"{watch}\">
<input type=\"hidden\" name=\"public\" value=\"true\">
<input type=\"hidden\" name=\"watched_already\" value=\"false\">
<button hx-post=\"/add/watch\" hx-target=\"#add-watch-{watch}\" hx-trigger=\"click\"
hx-swap=\"outerHTML\">wanna watch?</button>
</form>
"
)
.into_response()),
}
} else {
Ok("<a href='/login'>Login to add</a>".into_response())
}
}

View file

@ -98,8 +98,8 @@ impl Watch {
pub struct WatchQuest { pub struct WatchQuest {
pub user: Julid, pub user: Julid,
pub watch: Julid, pub watch: Julid,
pub is_public: bool, pub public: bool,
pub already_watched: bool, pub watched: bool,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]

View file

@ -13,6 +13,7 @@
<th>Title</th> <th>Title</th>
<th>Type</th> <th>Type</th>
<th>Year</th> <th>Year</th>
<th>Public watchlist?</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View file

@ -3,12 +3,9 @@
<td>{{watch.kind}}</td> <td>{{watch.kind}}</td>
<td> {% call m::get_or_default(watch.year(), "when??") -%}</td> <td> {% call m::get_or_default(watch.year(), "when??") -%}</td>
<td> <td>
<form id="add-watch-{{watch.id}}"> <span id="add-watch-{{watch.id}}">
<input type="hidden" name="watch" value="{{watch.id}}"> <span hx-get="/watch/status/{{watch.id}}?public=true" hx-target="this" hx-trigger="load, reveal"
<input type="hidden" name="public" value="true"> hx-swap="outerHTML">wanna watch?</span>
<input type="hidden" name="watched_already" value="false"> </span>
<button hx-post="/add/watch" hx-target="#add-watch-{{watch.id}}" hx-trigger="click"
hx-swap="OuterHTML">wanna watch?</button>
</form>
</td> </td>
</tr> </tr>