From 955946d6230a5da3a6ae0fda4703a06d84a24ea0 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Sun, 12 Jan 2025 16:15:13 +0100 Subject: [PATCH] feat: add smooth scroll --- Cargo.lock | 1 + crates/app/Cargo.toml | 4 +++ crates/app/src/lib.rs | 67 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 62 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4bbdda6..8adc19f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,6 +75,7 @@ dependencies = [ "serde_json", "server_fn", "thiserror 2.0.11", + "web-sys", ] [[package]] diff --git a/crates/app/Cargo.toml b/crates/app/Cargo.toml index fa37ac2..7767c5a 100644 --- a/crates/app/Cargo.toml +++ b/crates/app/Cargo.toml @@ -20,6 +20,10 @@ cfg-if.workspace = true thiserror.workspace = true reqwest = { version = "0.12.11", optional = true, features = ["json"] } serde_json = { version = "1.0.134", optional = true } +web-sys = { version = "0.3.76", features = [ + "ScrollBehavior", + "ScrollToOptions", +] } [features] default = [] diff --git a/crates/app/src/lib.rs b/crates/app/src/lib.rs index b8af9b8..6f317fc 100644 --- a/crates/app/src/lib.rs +++ b/crates/app/src/lib.rs @@ -1,8 +1,9 @@ use crate::error_template::{AppError, ErrorTemplate}; -use leptos::prelude::*; +use leptos::{ev::SubmitEvent, html, prelude::*}; use leptos_meta::*; use leptos_router::{components::*, StaticSegment}; +use message::Message; pub mod error_template; @@ -55,9 +56,49 @@ pub fn App() -> impl IntoView { } } +fn smooth_scroll_to_bottom() { + if let Some(window) = web_sys::window() { + if let Some(document) = window.document() { + if let Some(body) = document.get_element_by_id("messages") { + body.set_scroll_top(body.scroll_height()); + + leptos::logging::log!("moving to top"); + } + } + } +} + #[component] pub fn HomePage() -> impl IntoView { - let messages = message::get_messages(); + let (messages, set_messages) = signal( + message::get_messages() + .into_iter() + .enumerate() + .map(|(index, value)| (index, ArcRwSignal::new(value))) + .collect::>(), + ); + let (input, set_input) = signal("".to_string()); + + let on_submit = move |ev: SubmitEvent| { + // stop the page from reloading! + ev.prevent_default(); + + let messages_len = messages.get().len(); + let mut messages = set_messages.write(); + messages.push(( + messages_len, + ArcRwSignal::new(Message { + role: "user".into(), + content: input.get().into(), + }), + )); + + set_input.set("".into()); + + request_animation_frame(move || { + smooth_scroll_to_bottom(); + }); + }; view! {
@@ -70,11 +111,14 @@ pub fn HomePage() -> impl IntoView {
-
+
- {messages - .iter() - .map(|message| { + impl IntoView { )>{message.content.clone()}
} - }) - .collect_view()} + } + />
"Loading..."
-
+
+
-
+
+