diff --git a/Cargo.lock b/Cargo.lock index f92d4fc..52281b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,6 +155,7 @@ dependencies = [ "cfg-if", "fnord-ui", "http 1.1.0", + "human_bytes", "leptos", "leptos_axum", "leptos_meta", @@ -1229,6 +1230,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "human_bytes" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91f255a4535024abf7640cb288260811fc14794f62b063652ed349f9a6c2348e" + [[package]] name = "hydration_context" version = "0.2.0-beta" diff --git a/Cargo.toml b/Cargo.toml index 9d7db9a..c4bf0d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,7 @@ lib-package = "frontend" # The site root folder is where cargo-leptos generate all output. WARNING: all content of this folder will be erased on a rebuild. Use it in your server setup. site-root = "target/site" -hash-files = true +hash-files = false # The site-root relative folder where all compiled output (JS, WASM and CSS) is written # Defaults to pkg diff --git a/app/Cargo.toml b/app/Cargo.toml index 4416a09..26c99ea 100644 --- a/app/Cargo.toml +++ b/app/Cargo.toml @@ -29,6 +29,7 @@ simple_crypt = { version = "0.2.3", optional = true } bincode = { version = "1.3.3", optional = true } base64 = { version = "0.22.1", optional = true } anyhow.workspace = true +human_bytes = "0.4.3" [features] diff --git a/app/src/components/mod.rs b/app/src/components/mod.rs new file mode 100644 index 0000000..5d7bb2f --- /dev/null +++ b/app/src/components/mod.rs @@ -0,0 +1,2 @@ +pub mod status_bar; +pub mod torrents; diff --git a/app/src/components/status_bar.rs b/app/src/components/status_bar.rs new file mode 100644 index 0000000..836dce4 --- /dev/null +++ b/app/src/components/status_bar.rs @@ -0,0 +1,26 @@ +use fnord_ui::components::{Text, View}; +use human_bytes::human_bytes; +use leptos::prelude::*; + +use qbittorrent_rs_proto::transfer::ServerStateFull; + +#[component] +pub fn StatusBar(server_state: Signal) -> impl IntoView { + let dl_speed = move || human_bytes(server_state.get().dl_info_speed); + let up_speed = move || human_bytes(server_state.get().up_info_speed); + let dl_data = move || human_bytes(server_state.get().dl_info_data); + let up_data = move || human_bytes(server_state.get().up_info_data); + + view! { + + +
{move || dl_speed()}"/s"
+
{move || up_speed()}"/s"
+
+ +
"Downloaded: "{move || dl_data()}
+
"Uploaded: "{move || up_data()}
+
+
+ } +} diff --git a/app/src/components/torrents.rs b/app/src/components/torrents.rs new file mode 100644 index 0000000..60cbb24 --- /dev/null +++ b/app/src/components/torrents.rs @@ -0,0 +1,8 @@ +use leptos::prelude::*; + +#[component] +pub fn TorrentList() -> impl IntoView { + view! { +
+ } +} diff --git a/app/src/lib.rs b/app/src/lib.rs index 985f3b4..a77a91d 100644 --- a/app/src/lib.rs +++ b/app/src/lib.rs @@ -1,9 +1,12 @@ pub mod auth; mod routes; +mod components; + use crate::error_template::{AppError, ErrorTemplate}; use auth::{has_auth, Login}; +use components::status_bar::StatusBar; use leptos::{either::Either, prelude::*}; use leptos_meta::*; use leptos_router::{components::*, StaticSegment}; @@ -115,12 +118,13 @@ fn Dashboard() -> impl IntoView { use qbittorrent_rs_sse::sse_sync_maindata; // Create sse signal let data = sse_sync_maindata("/sse"); + let server_data = data.clone(); + let server_state = Signal::derive(move || server_data().server_state); view! { -
Count: {move || { view! {
-
"DL: "{data().server_state.dl_info_speed.to_string()}
-
"UP: "{data().server_state.up_info_speed.to_string()}
-
"Status: "{data().server_state.connection_status.to_string()}
-
}}}
+
+
"Torrent list will go here"
+ +
} } diff --git a/fnord_ui/src/components/mod.rs b/fnord_ui/src/components/mod.rs index 49e7621..f7c7d17 100644 --- a/fnord_ui/src/components/mod.rs +++ b/fnord_ui/src/components/mod.rs @@ -1,7 +1,11 @@ mod button; mod input; mod navbar; +mod typography; +mod view; pub use button::*; pub use input::*; pub use navbar::*; +pub use typography::*; +pub use view::*; diff --git a/fnord_ui/src/components/typography.rs b/fnord_ui/src/components/typography.rs new file mode 100644 index 0000000..e0bd978 --- /dev/null +++ b/fnord_ui/src/components/typography.rs @@ -0,0 +1,81 @@ +use leptos::html; +use leptos::prelude::*; +use tailwind_fuse::*; + +#[component] +pub fn H1( + #[prop(optional, into)] class: String, + #[prop(optional)] node_ref: NodeRef, + children: Children, +) -> impl IntoView { + view! { +

+ {children()} +

+ } +} + +#[component] +pub fn H2( + #[prop(optional, into)] class: String, + #[prop(optional)] node_ref: NodeRef, + children: Children, +) -> impl IntoView { + view! { +

+ {children()} +

+ } +} + +#[component] +pub fn H3( + #[prop(optional, into)] class: String, + #[prop(optional)] node_ref: NodeRef, + children: Children, +) -> impl IntoView { + view! { +

+ {children()} +

+ } +} + +#[component] +pub fn Text( + #[prop(optional, into)] class: String, + #[prop(optional)] node_ref: NodeRef, + children: Children, +) -> impl IntoView { + view! { +

+ {children()} +

+ } +} + +#[component] +pub fn TextSpan( + #[prop(optional, into)] class: String, + #[prop(optional)] node_ref: NodeRef, + children: Children, +) -> impl IntoView { + view! { + + {children()} + + } +} diff --git a/fnord_ui/src/components/view.rs b/fnord_ui/src/components/view.rs new file mode 100644 index 0000000..73c46c1 --- /dev/null +++ b/fnord_ui/src/components/view.rs @@ -0,0 +1,16 @@ +use leptos::html; +use leptos::prelude::*; +use tailwind_fuse::*; + +#[component] +pub fn View( + #[prop(optional, into)] class: String, + #[prop(optional)] node_ref: NodeRef, + children: Children, +) -> impl IntoView { + view! { +
+ {children()} +
+ } +} diff --git a/qbittorrent_rs/src/lib.rs b/qbittorrent_rs/src/lib.rs index 55c0864..fc501a4 100644 --- a/qbittorrent_rs/src/lib.rs +++ b/qbittorrent_rs/src/lib.rs @@ -76,7 +76,6 @@ impl QbtClient { #[tracing::instrument] pub async fn sync_maindata(&self, sid: String, rid: u64) -> Result { let url = format!("{}{}{}?rid={}", self.base_url, SYNC_API, MAINDATA_API, rid); - tracing::info!(url = ?url); let client = reqwest::Client::builder().build()?; let response = client diff --git a/qbittorrent_rs_sse/src/axum.rs b/qbittorrent_rs_sse/src/axum.rs index 96f0adf..c8c2313 100644 --- a/qbittorrent_rs_sse/src/axum.rs +++ b/qbittorrent_rs_sse/src/axum.rs @@ -1,25 +1,11 @@ -use core::panic; - use anyhow::anyhow; -use axum::http::StatusCode; use axum::response::sse::{Event, KeepAlive, Sse}; -use axum::{ - body::Body, - extract::{FromRef, Path, Request, State}, - http::header::{self, CONTENT_TYPE}, - middleware::{self, Next}, - response::{IntoResponse, Response}, - routing::{get, post}, - Extension, Router, ServiceExt, -}; use futures::stream; use futures::stream::Stream; -use futures::{TryStream, TryStreamExt}; +use futures::TryStreamExt; use leptos::prelude::*; use qbittorrent_rs::QbtClient; -use qbittorrent_rs_proto::sync::{MainData, SyncMainDataFull}; -use qbittorrent_rs_proto::transfer::ServerStateFull; -use serde::{Deserialize, Serialize}; +use qbittorrent_rs_proto::sync::MainData; use std::time::Duration; use tokio_stream::StreamExt as _;