liveview: Add `interpreter_glue_relative_uri (#1481)

* liveview: Add `interpreter_glue_relative_uri`

By utilizing `window.location.host` in the client-side JavaScript, we can easily derive the WebSocket URI from a relative path URI. This approach obviates the need for host address retrieval on the server side, unlike the method of serving glue code in liveview using `interpreter_glue`.

* liveview: Merge `.._relative_url` functionality

- Merged `.._relative_url` to current API `interpreter_glue`.
- Edit axum example to work with new feature.

* liveview: Fix clippy warning
This commit is contained in:
Seungwoo Kang 2023-09-27 06:35:17 +09:00 committed by GitHub
parent 517a43d765
commit 31780b3ede
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 28 deletions

View file

@ -19,11 +19,7 @@ async fn main() {
let addr: std::net::SocketAddr = ([127, 0, 0, 1], 3030).into(); let addr: std::net::SocketAddr = ([127, 0, 0, 1], 3030).into();
let view = dioxus_liveview::LiveViewPool::new(); let view = dioxus_liveview::LiveViewPool::new();
let index_page_with_glue = |glue: &str| {
let app = Router::new()
.route(
"/",
get(move || async move {
Html(format!( Html(format!(
r#" r#"
<!DOCTYPE html> <!DOCTYPE html>
@ -33,8 +29,23 @@ async fn main() {
{glue} {glue}
</html> </html>
"#, "#,
glue = dioxus_liveview::interpreter_glue(&format!("ws://{addr}/ws"))
)) ))
};
let app =
Router::new()
.route(
"/",
get(move || async move {
index_page_with_glue(&dioxus_liveview::interpreter_glue(&format!(
"ws://{addr}/ws"
)))
}),
)
.route(
"/as-path",
get(move || async move {
index_page_with_glue(&dioxus_liveview::interpreter_glue("/ws"))
}), }),
) )
.route( .route(

View file

@ -93,14 +93,49 @@ static MAIN_JS: &str = include_str!("./main.js");
/// This script that gets injected into your app connects this page to the websocket endpoint /// This script that gets injected into your app connects this page to the websocket endpoint
/// ///
/// Once the endpoint is connected, it will send the initial state of the app, and then start /// Once the endpoint is connected, it will send the initial state of the app, and then start
/// processing user events and returning edits to the liveview instance /// processing user events and returning edits to the liveview instance.
pub fn interpreter_glue(url: &str) -> String { ///
/// You can pass a relative path prefixed with "/", or enter a full URL including the protocol
/// (`ws:` or `wss:`) as an argument.
///
/// If you enter a relative path, the web client automatically prefixes the host address in
/// `window.location` when creating a web socket to LiveView.
///
/// ```
/// // Creates websocket connection to same host as current page
/// interpreter_glue("/api/liveview");
///
/// // Creates websocket connection to specified url
/// interpreter_glue("ws://localhost:8080/api/liveview");
/// ```
pub fn interpreter_glue(url_or_path: &str) -> String {
// If the url starts with a `/`, generate glue which reuses current host
let get_ws_url = if url_or_path.starts_with('/') {
r#"
let loc = window.location;
let new_url = "";
if (loc.protocol === "https:") {{
new_url = "wss:";
}} else {{
new_url = "ws:";
}}
new_url += "//" + loc.host + path;
return new_url;
"#
} else {
"return path;"
};
let js = &*INTERPRETER_JS; let js = &*INTERPRETER_JS;
let common = &*COMMON_JS; let common = &*COMMON_JS;
format!( format!(
r#" r#"
<script> <script>
var WS_ADDR = "{url}"; function __dioxusGetWsUrl(path) {{
{get_ws_url}
}}
var WS_ADDR = __dioxusGetWsUrl("{url_or_path}");
{js} {js}
{common} {common}
{MAIN_JS} {MAIN_JS}