mirror of
https://github.com/adoyle0/leptos-use.git
synced 2025-01-23 00:59:22 -05:00
Address review suggestion, update doc + book
This commit is contained in:
parent
325db84870
commit
12eb953c70
5 changed files with 173 additions and 103 deletions
|
@ -57,7 +57,7 @@ cargo test --all-features
|
|||
First you need to install
|
||||
|
||||
```shell
|
||||
cargo install mdbook-cmdrun trunk
|
||||
cargo install mdbook mdbook-cmdrun trunk
|
||||
```
|
||||
|
||||
To build the book go in your terminal into the docs/book folder
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
- [use_session_storage](storage/use_session_storage.md)
|
||||
- [use_storage](storage/use_storage.md)
|
||||
|
||||
# @WebSocket
|
||||
|
||||
- [use_websocket](websocket/use_websocket.md)
|
||||
|
||||
# Elements
|
||||
|
||||
- [use_active_element](elements/use_active_element.md)
|
||||
|
|
3
docs/book/src/websocket/use_websocket.md
Normal file
3
docs/book/src/websocket/use_websocket.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# use_websocket
|
||||
|
||||
<!-- cmdrun python3 ../extract_doc_comment.py websocket/use_websocket websocket -->
|
|
@ -77,34 +77,32 @@ fn Demo(cx: Scope) -> impl IntoView {
|
|||
} = use_websocket_with_options(
|
||||
cx,
|
||||
"wss://echo.websocket.events/".to_string(),
|
||||
UseWebSocketOptions {
|
||||
manual: true,
|
||||
onopen: Some(Box::new(move |e| {
|
||||
UseWebSocketOptions::default()
|
||||
.manual(true)
|
||||
.onopen(Some(Box::new(move |e| {
|
||||
set_history2.update(|history: &mut Vec<_>| {
|
||||
history.push(format! {"[onopen]: event {:?}", e.type_()})
|
||||
});
|
||||
})),
|
||||
onclose: Some(Box::new(move |e| {
|
||||
})))
|
||||
.onclose(Some(Box::new(move |e| {
|
||||
set_history2.update(|history: &mut Vec<_>| {
|
||||
history.push(format! {"[onclose]: event {:?}", e.type_()})
|
||||
});
|
||||
})),
|
||||
onerror: Some(Box::new(move |e| {
|
||||
})))
|
||||
.onerror(Some(Box::new(move |e| {
|
||||
set_history2.update(|history: &mut Vec<_>| {
|
||||
history.push(format! {"[onerror]: event {:?}", e.type_()})
|
||||
});
|
||||
})),
|
||||
onmessage: Some(Box::new(move |m| {
|
||||
})))
|
||||
.onmessage(Some(Box::new(move |m| {
|
||||
set_history2
|
||||
.update(|history: &mut Vec<_>| history.push(format! {"[onmessage]: {:?}", m}));
|
||||
})),
|
||||
onmessage_bytes: Some(Box::new(move |m| {
|
||||
})))
|
||||
.onmessage_bytes(Some(Box::new(move |m| {
|
||||
set_history2.update(|history: &mut Vec<_>| {
|
||||
history.push(format! {"[onmessage_bytes]: {:?}", m})
|
||||
});
|
||||
})),
|
||||
..Default::default()
|
||||
},
|
||||
}))),
|
||||
);
|
||||
|
||||
let open_connection2 = move |_| {
|
||||
|
|
|
@ -4,6 +4,7 @@ use core::fmt;
|
|||
use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
|
||||
use default_struct_builder::DefaultBuilder;
|
||||
use js_sys::Array;
|
||||
use wasm_bindgen::{prelude::*, JsCast, JsValue};
|
||||
use web_sys::{BinaryType, Event, MessageEvent, WebSocket};
|
||||
|
@ -12,91 +13,67 @@ pub use web_sys::CloseEvent;
|
|||
|
||||
use crate::utils::CloneableFnMutWithArg;
|
||||
|
||||
/// The current state of the `WebSocket` connection.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum UseWebSocketReadyState {
|
||||
Connecting,
|
||||
Open,
|
||||
Closing,
|
||||
Closed,
|
||||
}
|
||||
|
||||
impl fmt::Display for UseWebSocketReadyState {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
UseWebSocketReadyState::Connecting => write!(f, "Connecting"),
|
||||
UseWebSocketReadyState::Open => write!(f, "Open"),
|
||||
UseWebSocketReadyState::Closing => write!(f, "Closing"),
|
||||
UseWebSocketReadyState::Closed => write!(f, "Closed"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Options for `WebSocket`.
|
||||
// #[derive(DefaultBuilder)]
|
||||
#[derive(Clone)]
|
||||
pub struct UseWebSocketOptions {
|
||||
/// `WebSocket` connect callback.
|
||||
pub onopen: Option<Box<dyn CloneableFnMutWithArg<Event>>>,
|
||||
/// `WebSocket` message callback for text.
|
||||
pub onmessage: Option<Box<dyn CloneableFnMutWithArg<String>>>,
|
||||
/// `WebSocket` message callback for binary.
|
||||
pub onmessage_bytes: Option<Box<dyn CloneableFnMutWithArg<Vec<u8>>>>,
|
||||
/// `WebSocket` error callback.
|
||||
pub onerror: Option<Box<dyn CloneableFnMutWithArg<Event>>>,
|
||||
/// `WebSocket` close callback.
|
||||
pub onclose: Option<Box<dyn CloneableFnMutWithArg<CloseEvent>>>,
|
||||
|
||||
/// Retry times.
|
||||
pub reconnect_limit: Option<u64>,
|
||||
/// Retry interval(ms).
|
||||
pub reconnect_interval: Option<u64>,
|
||||
/// Manually starts connection
|
||||
pub manual: bool,
|
||||
/// Sub protocols
|
||||
pub protocols: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
impl Default for UseWebSocketOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
onopen: None,
|
||||
onmessage: None,
|
||||
onmessage_bytes: None,
|
||||
onerror: None,
|
||||
onclose: None,
|
||||
reconnect_limit: Some(3),
|
||||
reconnect_interval: Some(3 * 1000),
|
||||
manual: false,
|
||||
protocols: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return type of [`use_websocket`].
|
||||
#[derive(Clone)]
|
||||
pub struct UseWebsocketReturn<OpenFn, CloseFn, SendFn, SendBytesFn>
|
||||
where
|
||||
OpenFn: Fn() + Clone + 'static,
|
||||
CloseFn: Fn() + Clone + 'static,
|
||||
SendFn: Fn(String) + Clone + 'static,
|
||||
SendBytesFn: Fn(Vec<u8>) + Clone + 'static,
|
||||
{
|
||||
/// The current state of the `WebSocket` connection.
|
||||
pub ready_state: ReadSignal<UseWebSocketReadyState>,
|
||||
/// Latest text message received from `WebSocket`.
|
||||
pub message: ReadSignal<Option<String>>,
|
||||
/// Latest binary message received from `WebSocket`.
|
||||
pub message_bytes: ReadSignal<Option<Vec<u8>>>,
|
||||
/// The `WebSocket` instance.
|
||||
pub ws: Option<WebSocket>,
|
||||
|
||||
pub open: OpenFn,
|
||||
pub close: CloseFn,
|
||||
pub send: SendFn,
|
||||
pub send_bytes: SendBytesFn,
|
||||
}
|
||||
|
||||
/// Creating and managing a [Websocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) connection.
|
||||
///
|
||||
/// ## Demo
|
||||
///
|
||||
/// [Link to Demo](https://github.com/Synphonyte/leptos-use/tree/main/examples/use_websocket)
|
||||
///
|
||||
/// ## Usage
|
||||
///
|
||||
/// ```
|
||||
/// # use leptos::*;
|
||||
/// # use leptos_use::websocket::*;
|
||||
/// #
|
||||
/// # #[component]
|
||||
/// # fn Demo(cx: Scope) -> impl IntoView {
|
||||
/// let UseWebsocketReturn {
|
||||
/// ready_state,
|
||||
/// message,
|
||||
/// message_bytes,
|
||||
/// send,
|
||||
/// send_bytes,
|
||||
/// open,
|
||||
/// close,
|
||||
/// ..
|
||||
/// } = use_websocket(cx, "wss://echo.websocket.events/".to_string());
|
||||
///
|
||||
/// let send_message = move |_| {
|
||||
/// let m = "Hello, world!".to_string();
|
||||
/// send(m.clone());
|
||||
/// };
|
||||
///
|
||||
/// let send_byte_message = move |_| {
|
||||
/// let m = b"Hello, world!\r\n".to_vec();
|
||||
/// send_bytes(m.clone());
|
||||
/// };
|
||||
///
|
||||
/// let status = move || ready_state().to_string();
|
||||
///
|
||||
/// let connected = move || ready_state.get() == UseWebSocketReadyState::Open;
|
||||
///
|
||||
/// let open_connection = move |_| {
|
||||
/// open();
|
||||
/// };
|
||||
///
|
||||
/// let close_connection = move |_| {
|
||||
/// close();
|
||||
/// };
|
||||
///
|
||||
/// view! { cx,
|
||||
/// <div>
|
||||
/// <p>"status: " {status}</p>
|
||||
/// button on:click=send_message disabled=move || !connected()>"Send"</button>
|
||||
/// <button on:click=send_byte_message disabled=move || !connected()>"Send bytes"</button>
|
||||
/// <button on:click=open_connection disabled=connected>"Open"</button>
|
||||
/// <button on:click=close_connection disabled=move || !connected()>"Close"</button>
|
||||
/// <p>"Receive message: " {format! {"{:?}", message}}</p>
|
||||
/// <p>"Receive byte message: " {format! {"{:?}", message_bytes}}</p>
|
||||
/// </div>
|
||||
/// }
|
||||
/// # }
|
||||
/// ```
|
||||
// #[doc(cfg(feature = "websocket"))]
|
||||
pub fn use_websocket(
|
||||
cx: Scope,
|
||||
url: String,
|
||||
|
@ -110,7 +87,7 @@ pub fn use_websocket(
|
|||
}
|
||||
|
||||
/// Version of [`use_websocket`] that takes `UseWebSocketOptions`. See [`use_websocket`] for how to use.
|
||||
|
||||
// #[doc(cfg(feature = "websocket"))]
|
||||
pub fn use_websocket_with_options(
|
||||
cx: Scope,
|
||||
url: String,
|
||||
|
@ -254,7 +231,6 @@ pub fn use_websocket_with_options(
|
|||
}
|
||||
// onerror handler
|
||||
{
|
||||
// let reconnect = reconnect.clone();
|
||||
let onerror_closure = Closure::wrap(Box::new(move |e: Event| {
|
||||
if unmounted_ref.get_value() {
|
||||
return;
|
||||
|
@ -372,3 +348,92 @@ pub fn use_websocket_with_options(
|
|||
send_bytes,
|
||||
}
|
||||
}
|
||||
|
||||
/// The current state of the `WebSocket` connection.
|
||||
// #[doc(cfg(feature = "websocket"))]
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum UseWebSocketReadyState {
|
||||
Connecting,
|
||||
Open,
|
||||
Closing,
|
||||
Closed,
|
||||
}
|
||||
|
||||
impl fmt::Display for UseWebSocketReadyState {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
UseWebSocketReadyState::Connecting => write!(f, "Connecting"),
|
||||
UseWebSocketReadyState::Open => write!(f, "Open"),
|
||||
UseWebSocketReadyState::Closing => write!(f, "Closing"),
|
||||
UseWebSocketReadyState::Closed => write!(f, "Closed"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Options for [`use_websocket_with_options`].
|
||||
// #[doc(cfg(feature = "websocket"))]
|
||||
#[derive(DefaultBuilder, Clone)]
|
||||
pub struct UseWebSocketOptions {
|
||||
/// `WebSocket` connect callback.
|
||||
onopen: Option<Box<dyn CloneableFnMutWithArg<Event>>>,
|
||||
/// `WebSocket` message callback for text.
|
||||
onmessage: Option<Box<dyn CloneableFnMutWithArg<String>>>,
|
||||
/// `WebSocket` message callback for binary.
|
||||
onmessage_bytes: Option<Box<dyn CloneableFnMutWithArg<Vec<u8>>>>,
|
||||
/// `WebSocket` error callback.
|
||||
onerror: Option<Box<dyn CloneableFnMutWithArg<Event>>>,
|
||||
/// `WebSocket` close callback.
|
||||
onclose: Option<Box<dyn CloneableFnMutWithArg<CloseEvent>>>,
|
||||
/// Retry times.
|
||||
reconnect_limit: Option<u64>,
|
||||
/// Retry interval(ms).
|
||||
reconnect_interval: Option<u64>,
|
||||
/// Manually starts connection
|
||||
manual: bool,
|
||||
/// Sub protocols
|
||||
protocols: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
impl Default for UseWebSocketOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
onopen: None,
|
||||
onmessage: None,
|
||||
onmessage_bytes: None,
|
||||
onerror: None,
|
||||
onclose: None,
|
||||
reconnect_limit: Some(3),
|
||||
reconnect_interval: Some(3 * 1000),
|
||||
manual: false,
|
||||
protocols: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return type of [`use_websocket`].
|
||||
// #[doc(cfg(feature = "websocket"))]
|
||||
#[derive(Clone)]
|
||||
pub struct UseWebsocketReturn<OpenFn, CloseFn, SendFn, SendBytesFn>
|
||||
where
|
||||
OpenFn: Fn() + Clone + 'static,
|
||||
CloseFn: Fn() + Clone + 'static,
|
||||
SendFn: Fn(String) + Clone + 'static,
|
||||
SendBytesFn: Fn(Vec<u8>) + Clone + 'static,
|
||||
{
|
||||
/// The current state of the `WebSocket` connection.
|
||||
pub ready_state: ReadSignal<UseWebSocketReadyState>,
|
||||
/// Latest text message received from `WebSocket`.
|
||||
pub message: ReadSignal<Option<String>>,
|
||||
/// Latest binary message received from `WebSocket`.
|
||||
pub message_bytes: ReadSignal<Option<Vec<u8>>>,
|
||||
/// The `WebSocket` instance.
|
||||
pub ws: Option<WebSocket>,
|
||||
/// Opens the `WebSocket` connection
|
||||
pub open: OpenFn,
|
||||
/// Closes the `WebSocket` connection
|
||||
pub close: CloseFn,
|
||||
/// Sends `text` (string) based data
|
||||
pub send: SendFn,
|
||||
/// Sends binary data
|
||||
pub send_bytes: SendBytesFn,
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue