Add handler for editing quests.
This commit is contained in:
parent
d90011b619
commit
47d3fbc339
3 changed files with 157 additions and 11 deletions
|
@ -52,8 +52,8 @@ pub async fn app(db_pool: sqlx::SqlitePool) -> IntoMakeService<axum::Router> {
|
||||||
use signup::handlers::{get_create_user, get_signup_success, post_create_user};
|
use signup::handlers::{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_watch, get_watch_status, get_watches, post_add_new_watch,
|
edit_watch_quest, get_add_new_watch, get_watch, get_watch_status, get_watches,
|
||||||
post_add_watch_quest,
|
post_add_new_watch, post_add_watch_quest,
|
||||||
};
|
};
|
||||||
|
|
||||||
let conf = crate::conf::Config::get();
|
let conf = crate::conf::Config::get();
|
||||||
|
@ -80,6 +80,7 @@ pub async fn app(db_pool: sqlx::SqlitePool) -> IntoMakeService<axum::Router> {
|
||||||
.route("/watch", get(get_watch))
|
.route("/watch", get(get_watch))
|
||||||
.route("/watch/:watch", get(get_watch))
|
.route("/watch/:watch", get(get_watch))
|
||||||
.route("/watch/status/:watch", get(get_watch_status))
|
.route("/watch/status/:watch", get(get_watch_status))
|
||||||
|
.route("/quest/edit", post(edit_watch_quest))
|
||||||
.route("/title-search", get(get_search_watch))
|
.route("/title-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(
|
||||||
|
|
|
@ -57,6 +57,33 @@ impl IntoResponse for AddError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Error]
|
||||||
|
pub struct EditError(#[from] EditErrorKind);
|
||||||
|
|
||||||
|
#[Error]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum EditErrorKind {
|
||||||
|
UnknownDBError,
|
||||||
|
NotSignedIn,
|
||||||
|
NotFound,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoResponse for EditError {
|
||||||
|
fn into_response(self) -> Response {
|
||||||
|
match &self.0 {
|
||||||
|
EditErrorKind::UnknownDBError => {
|
||||||
|
(StatusCode::INTERNAL_SERVER_ERROR, format!("{self}")).into_response()
|
||||||
|
}
|
||||||
|
EditErrorKind::NotSignedIn => (
|
||||||
|
StatusCode::OK,
|
||||||
|
"Ope, you need to sign in first!".to_string(),
|
||||||
|
)
|
||||||
|
.into_response(),
|
||||||
|
EditErrorKind::NotFound => (StatusCode::OK, "Could not find watch").into_response(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-************************************************************************
|
//-************************************************************************
|
||||||
// Types for receiving arguments from forms
|
// Types for receiving arguments from forms
|
||||||
//-************************************************************************
|
//-************************************************************************
|
||||||
|
@ -82,6 +109,12 @@ pub struct PostAddExistingWatch {
|
||||||
pub public: bool,
|
pub public: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, PartialEq, Eq)]
|
||||||
|
pub struct PostEditQuest {
|
||||||
|
pub watch: String,
|
||||||
|
pub act: String,
|
||||||
|
}
|
||||||
|
|
||||||
//-************************************************************************
|
//-************************************************************************
|
||||||
// handlers
|
// handlers
|
||||||
//-************************************************************************
|
//-************************************************************************
|
||||||
|
@ -184,6 +217,110 @@ pub async fn add_watch_quest_impl(pool: &SqlitePool, quest: &WatchQuest) -> Resu
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[axum::debug_handler]
|
||||||
|
pub async fn edit_watch_quest(
|
||||||
|
auth: AuthSession,
|
||||||
|
State(pool): State<SqlitePool>,
|
||||||
|
Form(form): Form<PostEditQuest>,
|
||||||
|
) -> Result<impl IntoResponse, EditError> {
|
||||||
|
if let Some(user) = auth.user {
|
||||||
|
let watch = Julid::from_str(form.watch.trim()).map_err(|_| EditErrorKind::NotFound)?;
|
||||||
|
Ok(
|
||||||
|
edit_watch_quest_impl(&pool, form.act.trim(), user.id, watch)
|
||||||
|
.await?
|
||||||
|
.into_response(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// todo: return editerror that prompts a login
|
||||||
|
let resp = Redirect::to("/login");
|
||||||
|
let mut resp = resp.into_response();
|
||||||
|
resp.headers_mut()
|
||||||
|
.insert("HX-Redirect", HeaderValue::from_str("/login").unwrap());
|
||||||
|
Ok(resp.into_response())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn edit_watch_quest_impl(
|
||||||
|
pool: &SqlitePool,
|
||||||
|
action: &str,
|
||||||
|
user: Julid,
|
||||||
|
watch: Julid,
|
||||||
|
) -> Result<WatchStatusMenus, EditErrorKind> {
|
||||||
|
let quest: Option<WatchQuest> = query_as(GET_QUEST_QUERY)
|
||||||
|
.bind(user)
|
||||||
|
.bind(watch)
|
||||||
|
.fetch_optional(pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!("Got error from checking watch status: {e:?}");
|
||||||
|
EditErrorKind::UnknownDBError
|
||||||
|
})?;
|
||||||
|
if let Some(quest) = quest {
|
||||||
|
match action {
|
||||||
|
"remove" => {
|
||||||
|
sqlx::query!(
|
||||||
|
"delete from watch_quests where user = ? and watch = ?",
|
||||||
|
user,
|
||||||
|
watch
|
||||||
|
)
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!("Error removing quest: {e}");
|
||||||
|
EditErrorKind::UnknownDBError
|
||||||
|
})?;
|
||||||
|
Ok(WatchStatusMenus { watch, quest: None })
|
||||||
|
}
|
||||||
|
"watched" => {
|
||||||
|
let watched = !quest.watched;
|
||||||
|
sqlx::query!(
|
||||||
|
"update watch_quests set watched = ? where user = ? and watch = ?",
|
||||||
|
watched,
|
||||||
|
user,
|
||||||
|
watch
|
||||||
|
)
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!("Error updating quest: {e}");
|
||||||
|
EditErrorKind::UnknownDBError
|
||||||
|
})?;
|
||||||
|
let quest = WatchQuest { watched, ..quest };
|
||||||
|
Ok(WatchStatusMenus {
|
||||||
|
watch,
|
||||||
|
quest: Some(quest),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
"viz" => {
|
||||||
|
let public = !quest.public;
|
||||||
|
sqlx::query!(
|
||||||
|
"update watch_quests set public = ? where user = ? and watch = ?",
|
||||||
|
public,
|
||||||
|
user,
|
||||||
|
watch
|
||||||
|
)
|
||||||
|
.execute(pool)
|
||||||
|
.await
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!("Error updating quest: {e}");
|
||||||
|
EditErrorKind::UnknownDBError
|
||||||
|
})?;
|
||||||
|
let quest = WatchQuest { public, ..quest };
|
||||||
|
Ok(WatchStatusMenus {
|
||||||
|
watch,
|
||||||
|
quest: Some(quest),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
_ => Ok(WatchStatusMenus {
|
||||||
|
watch,
|
||||||
|
quest: Some(quest),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(EditErrorKind::NotFound)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A single Watch
|
/// A single Watch
|
||||||
pub async fn get_watch(
|
pub async fn get_watch(
|
||||||
auth: AuthSession,
|
auth: AuthSession,
|
||||||
|
|
|
@ -1,43 +1,51 @@
|
||||||
{% match quest %}
|
{% match quest %}
|
||||||
{% when Some with (q) %}
|
{% when Some with (q) %}
|
||||||
|
|
||||||
{% let public %}
|
{% let viz %}
|
||||||
{% let np %}
|
{% let np %}
|
||||||
{% if q.public -%}
|
{% if q.public -%}
|
||||||
{% let public = "public" %}
|
{% let viz = "public" %}
|
||||||
{% let np = "private" %}
|
{% let np = "private" %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% let public = "private" %}
|
{% let viz = "private" %}
|
||||||
{% let np = "public" %}
|
{% let np = "public" %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
||||||
{% let status %}
|
{% let status %}
|
||||||
{% if q.watched -%}
|
{% if q.watched -%}
|
||||||
{% let status = "want to watch" %}
|
|
||||||
{% else %}
|
|
||||||
{% let status = "watched" %}
|
{% let status = "watched" %}
|
||||||
|
{% else %}
|
||||||
|
{% let status = "want to watch" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Added</td>
|
<td>{{- status -}}</td>
|
||||||
<td>{{- public -}}</td>
|
<td>{{- viz -}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<form id="edit-quest-{{self.watch}}">
|
<form id="edit-quest-{{self.watch}}">
|
||||||
<button hx-post="/edit/quest" hx-target="#add-watch-{{self.watch}}" hx-trigger="click"
|
{% if q.watched %}
|
||||||
|
<button hx-post="/quest/edit" hx-target="#add-watch-{{self.watch}}" hx-trigger="click"
|
||||||
hx-swap="outerHTML">remove</button>
|
hx-swap="outerHTML">remove</button>
|
||||||
<input type="hidden" name="watch" value="{{self.watch}}">
|
<input type="hidden" name="watch" value="{{self.watch}}">
|
||||||
<input type="hidden" name="act" value="remove">
|
<input type="hidden" name="act" value="remove">
|
||||||
|
{% else %}
|
||||||
|
<button hx-post="/quest/edit" hx-target="#add-watch-{{self.watch}}" hx-trigger="click"
|
||||||
|
hx-swap="outerHTML">mark watched</button>
|
||||||
|
<input type="hidden" name="watch" value="{{self.watch}}">
|
||||||
|
<input type="hidden" name="act" value="watched">
|
||||||
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<form id="edit-visibility-{{self.watch}}">
|
<form id="edit-visibility-{{self.watch}}">
|
||||||
<button hx-post="/edit/quest" hx-target="#add-watch-{{self.watch}}" hx-trigger="click"
|
<button hx-post="/quest/edit" hx-target="#add-watch-{{self.watch}}" hx-trigger="click"
|
||||||
hx-swap="outerHTML">mark as {{ np }}</button>
|
hx-swap="outerHTML">mark as {{ np }}</button>
|
||||||
<input type="hidden" name="watch" value="{{self.watch}}">
|
<input type="hidden" name="watch" value="{{self.watch}}">
|
||||||
|
<input type="hidden" name="act" value="viz">
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
Loading…
Reference in a new issue