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

View file

@ -78,6 +78,11 @@ pub struct SearchQuery {
pub year: Option<i64>,
}
#[derive(Debug, Default, Clone, Deserialize, PartialEq, Eq)]
pub struct StatusQuery {
pub public: bool,
}
// kinda the main form?
#[derive(Debug, Default, Deserialize, PartialEq, Eq)]
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 quest = WatchQuest {
user: user.id,
is_public: !form.private,
already_watched: form.watched_already,
public: !form.private,
watched: form.watched_already,
watch: watch_id,
};
add_watch_quest_impl(&pool, &quest)
@ -172,8 +177,8 @@ pub async fn post_add_watch_quest(
let quest = WatchQuest {
user: user.id,
watch: Julid::from_string(&form.watch).unwrap(),
is_public: form.public,
already_watched: form.watched_already,
public: form.public,
watched: form.watched_already,
};
add_watch_quest_impl(&pool, &quest)
.await
@ -193,8 +198,8 @@ pub async fn add_watch_quest_impl(pool: &SqlitePool, quest: &WatchQuest) -> Resu
query(ADD_WATCH_QUEST_QUERY)
.bind(quest.user)
.bind(quest.watch)
.bind(quest.is_public)
.bind(quest.already_watched)
.bind(quest.public)
.bind(quest.watched)
.execute(pool)
.await
.map_err(|err| {
@ -275,3 +280,41 @@ pub async fn get_search_watch(
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 user: Julid,
pub watch: Julid,
pub is_public: bool,
pub already_watched: bool,
pub public: bool,
pub watched: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]

View file

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

View file

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