feat: added tcp
sorry Judah
This commit is contained in:
+50
-33
@@ -1,29 +1,33 @@
|
||||
use chrono::{DateTime, offset::Utc};
|
||||
use chrono::{offset::Utc, DateTime};
|
||||
use leptos::prelude::*;
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[cfg(feature = "ssr")]
|
||||
use {
|
||||
sqlx::SqlitePool,
|
||||
leptos::server_fn::error::NoCustomError,
|
||||
crate::db::user
|
||||
};
|
||||
use {crate::db::user, leptos::server_fn::error::NoCustomError, sqlx::SqlitePool};
|
||||
|
||||
pub fn format_delta(time: chrono::TimeDelta) -> String {
|
||||
let seconds = time.num_seconds();
|
||||
|
||||
match seconds {
|
||||
0..=59 => format!("{} second{} ago", seconds, if seconds == 1 {""} else {"s"}),
|
||||
0..=59 => format!(
|
||||
"{} second{} ago",
|
||||
seconds,
|
||||
if seconds == 1 { "" } else { "s" }
|
||||
),
|
||||
60..=3599 => {
|
||||
let minutes = seconds / 60;
|
||||
format!("{} minute{} ago", minutes, if minutes == 1 {""} else {"s"})
|
||||
format!(
|
||||
"{} minute{} ago",
|
||||
minutes,
|
||||
if minutes == 1 { "" } else { "s" }
|
||||
)
|
||||
}
|
||||
3600..=86399 => {
|
||||
let hours = seconds / 3600;
|
||||
format!("{} hours{} ago", hours, if hours == 1 {""} else {"s"})
|
||||
format!("{} hours{} ago", hours, if hours == 1 { "" } else { "s" })
|
||||
}
|
||||
_ => {
|
||||
let days = seconds / 86400;
|
||||
format!("{} day{} ago", days, if days == 1 {""} else {"s"})
|
||||
format!("{} day{} ago", days, if days == 1 { "" } else { "s" })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,14 +48,14 @@ impl std::cmp::PartialEq for User {
|
||||
pub struct DbUser {
|
||||
user_id: i64,
|
||||
user_name: String,
|
||||
last_active: Option<i64>
|
||||
last_active: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
pub struct PubUser {
|
||||
user_id: i64,
|
||||
user_name: String,
|
||||
last_active: Option<DateTime<Utc>>
|
||||
last_active: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
#[server]
|
||||
@@ -59,15 +63,14 @@ async fn delete_user(user_id: i64) -> Result<(), ServerFnError> {
|
||||
let user = user::get_auth_session().await?;
|
||||
|
||||
if user.is_none() {
|
||||
return Err(ServerFnError::<NoCustomError>::ServerError("You are not signed in!".to_owned()));
|
||||
return Err(ServerFnError::<NoCustomError>::ServerError(
|
||||
"You are not signed in!".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
let pool = expect_context::<SqlitePool>();
|
||||
|
||||
sqlx::query!(
|
||||
"DELETE FROM users WHERE user_id = ?",
|
||||
user_id
|
||||
)
|
||||
sqlx::query!("DELETE FROM users WHERE user_id = ?", user_id)
|
||||
.execute(&pool)
|
||||
.await?;
|
||||
|
||||
@@ -79,7 +82,9 @@ async fn reset_password(user_id: i64, password: String) -> Result<(), ServerFnEr
|
||||
let user = user::get_auth_session().await?;
|
||||
|
||||
if user.is_none() {
|
||||
return Err(ServerFnError::<NoCustomError>::ServerError("You are not signed in!".to_owned()));
|
||||
return Err(ServerFnError::<NoCustomError>::ServerError(
|
||||
"You are not signed in!".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
let pool = expect_context::<SqlitePool>();
|
||||
@@ -96,15 +101,21 @@ pub fn RenderUser(refresh_user_list: Action<(), ()>, user: PubUser) -> impl Into
|
||||
#[cfg_attr(feature = "ssr", allow(unused_variables))]
|
||||
let UseIntervalReturn { counter, .. } = use_interval(1000);
|
||||
#[cfg_attr(feature = "ssr", allow(unused_variables))]
|
||||
let (time_ago, set_time_ago) = signal(user.last_active.map(|active| format_delta(Utc::now() - active)));
|
||||
let (time_ago, set_time_ago) = signal(
|
||||
user.last_active
|
||||
.map(|active| format_delta(Utc::now() - active)),
|
||||
);
|
||||
|
||||
#[cfg(feature = "hydrate")]
|
||||
Effect::watch(
|
||||
move || counter.get(),
|
||||
move |_, _, _| {
|
||||
set_time_ago(user.last_active.map(|active| format_delta(Utc::now() - active)));
|
||||
set_time_ago(
|
||||
user.last_active
|
||||
.map(|active| format_delta(Utc::now() - active)),
|
||||
);
|
||||
},
|
||||
false
|
||||
false,
|
||||
);
|
||||
|
||||
let dialog_ref = NodeRef::<leptos::html::Dialog>::new();
|
||||
@@ -220,23 +231,27 @@ async fn list_users() -> Result<Vec<PubUser>, ServerFnError> {
|
||||
let user = user::get_auth_session().await?;
|
||||
|
||||
if user.is_none() {
|
||||
return Err(ServerFnError::<NoCustomError>::ServerError("You are not signed in!".to_owned()));
|
||||
return Err(ServerFnError::<NoCustomError>::ServerError(
|
||||
"You are not signed in!".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
use futures::stream::StreamExt;
|
||||
|
||||
let pool = expect_context::<SqlitePool>();
|
||||
|
||||
let users = sqlx::query_as!(
|
||||
DbUser,
|
||||
"SELECT user_id, user_name, last_active FROM users"
|
||||
)
|
||||
let users = sqlx::query_as!(DbUser, "SELECT user_id, user_name, last_active FROM users")
|
||||
.fetch(&pool)
|
||||
.map(|user| user.map(|u| PubUser {
|
||||
user_id: u.user_id,
|
||||
user_name: u.user_name,
|
||||
last_active: u.last_active.map(|ts| DateTime::from_timestamp(ts, 0)).flatten()
|
||||
}))
|
||||
.map(|user| {
|
||||
user.map(|u| PubUser {
|
||||
user_id: u.user_id,
|
||||
user_name: u.user_name,
|
||||
last_active: u
|
||||
.last_active
|
||||
.map(|ts| DateTime::from_timestamp(ts, 0))
|
||||
.flatten(),
|
||||
})
|
||||
})
|
||||
.collect::<Vec<Result<_, _>>>()
|
||||
.await;
|
||||
|
||||
@@ -250,7 +265,9 @@ async fn add_user(name: String, password: String) -> Result<(), ServerFnError> {
|
||||
let user = user::get_auth_session().await?;
|
||||
|
||||
if user.is_none() {
|
||||
return Err(ServerFnError::<NoCustomError>::ServerError("You are not signed in!".to_owned()));
|
||||
return Err(ServerFnError::<NoCustomError>::ServerError(
|
||||
"You are not signed in!".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
let pool = expect_context::<SqlitePool>();
|
||||
|
||||
Reference in New Issue
Block a user