moves log state up to App so it persists across route changes, moves wait during setup for webview to start to the async runtime so it doesn't block the setup fn from starting the webview.
This commit is contained in:
parent
dd1744f326
commit
f25e9d6286
|
@ -4,6 +4,7 @@ use std::{
|
|||
io::{BufRead, BufReader},
|
||||
path::PathBuf,
|
||||
process::{Child, Command, Stdio},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use tauri::{utils, AppHandle, Manager};
|
||||
|
@ -94,8 +95,17 @@ pub fn run_zebrad() -> (Child, Receiver<String>) {
|
|||
(zebrad_child, output_receiver)
|
||||
}
|
||||
|
||||
pub fn spawn_logs_emitter(mut output_receiver: Receiver<String>, app_handle: AppHandle) {
|
||||
pub fn spawn_logs_emitter(
|
||||
mut output_receiver: Receiver<String>,
|
||||
app_handle: AppHandle,
|
||||
should_wait_for_webview: bool,
|
||||
) {
|
||||
tauri::async_runtime::spawn(async move {
|
||||
// Wait for webview to start
|
||||
if should_wait_for_webview {
|
||||
tokio::time::sleep(Duration::from_secs(3)).await;
|
||||
}
|
||||
|
||||
// Exit the task once the channel is closed and empty.
|
||||
while let Some(output) = output_receiver.recv().await {
|
||||
if let Err(error) = app_handle.emit("log", output) {
|
||||
|
|
|
@ -37,7 +37,7 @@ async fn save_config(app_handle: AppHandle, new_config: String) -> Result<String
|
|||
app_handle
|
||||
.state::<AppState>()
|
||||
.insert_zebrad_child(zebrad_child);
|
||||
spawn_logs_emitter(zebrad_output_receiver, app_handle);
|
||||
spawn_logs_emitter(zebrad_output_receiver, app_handle, false);
|
||||
|
||||
Ok(old_config_contents)
|
||||
}
|
||||
|
@ -54,10 +54,7 @@ fn main() {
|
|||
tauri::Builder::default()
|
||||
.manage(AppState::new(zebrad_child))
|
||||
.setup(|app| {
|
||||
// Wait for webview to start
|
||||
std::thread::sleep(Duration::from_secs(3));
|
||||
|
||||
spawn_logs_emitter(zebrad_output_receiver, app.handle().clone());
|
||||
spawn_logs_emitter(zebrad_output_receiver, app.handle().clone(), true);
|
||||
Ok(())
|
||||
})
|
||||
.invoke_handler(tauri::generate_handler![save_config, read_config])
|
||||
|
|
56
src/App.tsx
56
src/App.tsx
|
@ -1,6 +1,13 @@
|
|||
import { Router, Route, RouteSectionProps, A, useMatch } from "@solidjs/router";
|
||||
import { css, styled } from "solid-styled-components";
|
||||
|
||||
import { listen, Event, UnlistenFn } from "@tauri-apps/api/event";
|
||||
|
||||
import { createSignal, onCleanup, onMount } from "solid-js";
|
||||
|
||||
import { EXAMPLE_LOGS } from "./tests/example_data";
|
||||
import { MAX_NUM_LOG_LINES } from "./constants";
|
||||
|
||||
import { NAVIGATION_BAR_HEIGHT } from "./constants";
|
||||
import Logs from "./pages/Logs";
|
||||
import Configuration from "./pages/Configure";
|
||||
|
@ -68,9 +75,56 @@ const AppContainer = ({ children }: RouteSectionProps) => (
|
|||
);
|
||||
|
||||
function App() {
|
||||
const is_tauri_app = window.hasOwnProperty("__TAURI_INTERNALS__");
|
||||
const [logs, set_logs] = createSignal<Array<string>>([]);
|
||||
|
||||
const is_at_bottom = () => {
|
||||
const y_bottom = Math.ceil(window.scrollY) + window.innerHeight;
|
||||
return y_bottom >= document.body.scrollHeight;
|
||||
};
|
||||
|
||||
const scroll_to_bottom = () => {
|
||||
window.scroll(0, document.body.scrollHeight);
|
||||
};
|
||||
|
||||
if (is_tauri_app) {
|
||||
let stop_listening: UnlistenFn;
|
||||
|
||||
onMount(async () => {
|
||||
stop_listening = await listen("log", (event: Event<string>) => {
|
||||
const was_at_bottom = is_at_bottom();
|
||||
|
||||
set_logs([...logs().slice(-MAX_NUM_LOG_LINES), event.payload]);
|
||||
|
||||
if (was_at_bottom) {
|
||||
scroll_to_bottom();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
onCleanup(() => stop_listening());
|
||||
} else {
|
||||
let example_log_index = 0;
|
||||
setInterval(() => {
|
||||
const was_at_bottom = is_at_bottom();
|
||||
|
||||
set_logs([
|
||||
...logs().slice(-MAX_NUM_LOG_LINES),
|
||||
EXAMPLE_LOGS[example_log_index],
|
||||
]);
|
||||
|
||||
// TODO: check if it's the logs page? May be easier to do if this logic is moved to `AppContainer`.
|
||||
if (was_at_bottom) {
|
||||
scroll_to_bottom();
|
||||
}
|
||||
|
||||
example_log_index = (example_log_index + 1) % EXAMPLE_LOGS.length;
|
||||
}, 100);
|
||||
}
|
||||
|
||||
return (
|
||||
<Router root={AppContainer}>
|
||||
<Route path="/" component={Logs} />
|
||||
<Route path="/" component={() => <Logs logs={logs} />} />
|
||||
<Route path="/configure" component={Configuration} />
|
||||
</Router>
|
||||
);
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
import { listen, Event, UnlistenFn } from "@tauri-apps/api/event";
|
||||
|
||||
import { createSignal, onCleanup, onMount, For } from "solid-js";
|
||||
import { For, Accessor } from "solid-js";
|
||||
import { styled } from "solid-styled-components";
|
||||
|
||||
import { EXAMPLE_LOGS } from "../tests/example_data";
|
||||
import { MAX_NUM_LOG_LINES } from "../constants";
|
||||
|
||||
const LogContainer = styled("div")`
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
|
@ -68,53 +63,7 @@ const Log = ({ children }: { children: string }) => {
|
|||
}
|
||||
};
|
||||
|
||||
const Logs = () => {
|
||||
const is_tauri_app = window.hasOwnProperty("__TAURI_INTERNALS__");
|
||||
const [logs, set_logs] = createSignal<Array<string>>([]);
|
||||
|
||||
const is_at_bottom = () => {
|
||||
const y_bottom = Math.ceil(window.scrollY) + window.innerHeight;
|
||||
return y_bottom >= document.body.scrollHeight;
|
||||
};
|
||||
|
||||
const scroll_to_bottom = () => {
|
||||
window.scroll(0, document.body.scrollHeight);
|
||||
};
|
||||
|
||||
if (is_tauri_app) {
|
||||
let stop_listening: UnlistenFn;
|
||||
|
||||
onMount(async () => {
|
||||
stop_listening = await listen("log", (event: Event<string>) => {
|
||||
const was_at_bottom = is_at_bottom();
|
||||
|
||||
set_logs([...logs().slice(-MAX_NUM_LOG_LINES), event.payload]);
|
||||
|
||||
if (was_at_bottom) {
|
||||
scroll_to_bottom();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
onCleanup(() => stop_listening());
|
||||
} else {
|
||||
let example_log_index = 0;
|
||||
setInterval(() => {
|
||||
const was_at_bottom = is_at_bottom();
|
||||
|
||||
set_logs([
|
||||
...logs().slice(-MAX_NUM_LOG_LINES),
|
||||
EXAMPLE_LOGS[example_log_index],
|
||||
]);
|
||||
|
||||
if (was_at_bottom) {
|
||||
scroll_to_bottom();
|
||||
}
|
||||
|
||||
example_log_index = (example_log_index + 1) % EXAMPLE_LOGS.length;
|
||||
}, 100);
|
||||
}
|
||||
|
||||
const Logs = ({ logs }: { logs: Accessor<string[]> }) => {
|
||||
return (
|
||||
<LogContainer>
|
||||
<For each={logs()} fallback={<Log>Waiting for zebrad to start...</Log>}>
|
||||
|
|
Loading…
Reference in New Issue