diff --git a/dist-isolation/index.js b/dist-isolation/index.js index 78dd47d77..8312ca110 100644 --- a/dist-isolation/index.js +++ b/dist-isolation/index.js @@ -1,4 +1,5 @@ window.__TAURI_ISOLATION_HOOK__ = (payload) => { + console.log("Isolation hook called with payload:", payload); // TODO: Prevent command execution // TODO: Perhaps whitelist commands return payload diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 4a1ced9b0..84c088e11 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2976,6 +2976,18 @@ dependencies = [ "smallvec", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "nodrop" version = "0.1.14" @@ -5052,6 +5064,7 @@ dependencies = [ "log4rs", "minotari_node_grpc_client", "minotari_wallet_grpc_client", + "nix", "rand 0.8.5", "reqwest 0.12.5", "sanitize-filename", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 4f753f03d..fb49589c3 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -55,6 +55,7 @@ async-trait = "0.1.81" sysinfo = "0.31.2" log4rs = "1.3.0" keyring = "3.0.5" +nix = {version ="0.29.0", features = ["signal"] } # static bind lzma xz2 = { version = "0.1.7", features = ["static"] } diff --git a/src-tauri/src/binary_resolver.rs b/src-tauri/src/binary_resolver.rs index d95be57db..f575c78f1 100644 --- a/src-tauri/src/binary_resolver.rs +++ b/src-tauri/src/binary_resolver.rs @@ -121,6 +121,8 @@ impl LatestVersionApiAdapter for GithubReleasesAdapter { name_suffix = "linux-x86_64.zip"; } + info!(target: LOG_TARGET, "Looking for platform with suffix: {}", name_suffix); + let platform = version .assets .iter() diff --git a/src-tauri/src/cpu_miner.rs b/src-tauri/src/cpu_miner.rs index a506b72db..40f3d781a 100644 --- a/src-tauri/src/cpu_miner.rs +++ b/src-tauri/src/cpu_miner.rs @@ -40,6 +40,8 @@ impl CpuMiner { cpu_miner_config: &CpuMinerConfig, local_mm_proxy: &MmProxyManager, base_path: PathBuf, + cache_dir: PathBuf, + log_dir: PathBuf, window: tauri::Window, ) -> Result<(), anyhow::Error> { if self.watcher_task.is_some() { @@ -54,7 +56,7 @@ impl CpuMiner { local_mm_proxy .start( app_shutdown.clone(), - base_path, + base_path.clone(), cpu_miner_config.tari_address.clone(), window.clone(), ) @@ -69,7 +71,8 @@ impl CpuMiner { } }; let xmrig = XmrigAdapter::new(xmrig_node_connection, "44AFFq5kSiGBoZ4NMDwYtN18obc8AemS33DBLWs3H7otXft3XjrpDtQGv7SqSsaBYBb98uNbr2VBBEt7f2wfn3RVGQBEP3A".to_string() ); - let (mut _rx, mut xmrig_child, client) = xmrig.spawn(window.clone())?; + let (mut _rx, mut xmrig_child, client) = + xmrig.spawn(cache_dir, log_dir, base_path, window.clone())?; self.api_client = Some(client); self.watcher_task = Some(tauri::async_runtime::spawn(async move { diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index dbd5b809f..4c486919d 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -17,6 +17,7 @@ mod node_manager; mod process_adapter; mod wallet_manager; +mod process_killer; mod wallet_adapter; use crate::cpu_miner::CpuMiner; @@ -65,6 +66,7 @@ async fn setup_application<'r>( }, ); let data_dir = app.path_resolver().app_local_data_dir().unwrap(); + let cache_dir = app.path_resolver().app_cache_dir().unwrap(); let task1 = state .node_manager .ensure_started(state.shutdown.to_signal(), data_dir.clone(), window.clone()) @@ -81,11 +83,10 @@ async fn setup_application<'r>( e.to_string() }); - let task3 = - XmrigAdapter::ensure_latest(cache_dir().unwrap(), false, window.clone()).map_err(|e| { - error!(target: LOG_TARGET, "Could not download xmrig: {:?}", e); - e.to_string() - }); + let task3 = XmrigAdapter::ensure_latest(cache_dir, false, window.clone()).map_err(|e| { + error!(target: LOG_TARGET, "Could not download xmrig: {:?}", e); + e.to_string() + }); match try_join!(task1, task2, task3) { Ok(_) => { @@ -133,6 +134,8 @@ async fn start_mining<'r>( &config, &mm_proxy_manager, app.path_resolver().app_local_data_dir().unwrap(), + app.path_resolver().app_cache_dir().unwrap(), + app.path_resolver().app_log_dir().unwrap(), window.clone(), ) .await diff --git a/src-tauri/src/merge_mining_adapter.rs b/src-tauri/src/merge_mining_adapter.rs index 0b1c75401..78607ada7 100644 --- a/src-tauri/src/merge_mining_adapter.rs +++ b/src-tauri/src/merge_mining_adapter.rs @@ -3,6 +3,8 @@ use crate::process_adapter::{ProcessAdapter, ProcessInstance, StatusMonitor}; use anyhow::Error; use async_trait::async_trait; use dirs_next::data_local_dir; +use log::warn; +use std::fs; use std::path::PathBuf; use tari_common_types::tari_address::TariAddress; use tari_shutdown::Shutdown; @@ -10,6 +12,8 @@ use tokio::runtime::Handle; use tokio::select; use tokio::task::JoinHandle; +const LOG_TARGET: &str = "tari::universe::merge_mining_proxy_adapter"; + pub struct MergeMiningProxyAdapter { force_download: bool, pub(crate) tari_address: TariAddress, @@ -30,16 +34,13 @@ impl ProcessAdapter for MergeMiningProxyAdapter { fn spawn_inner( &self, - _log_folder: PathBuf, + data_dir: PathBuf, window: tauri::Window, ) -> Result<(Self::Instance, Self::StatusMonitor), Error> { let inner_shutdown = Shutdown::new(); let shutdown_signal = inner_shutdown.to_signal(); - let working_dir = data_local_dir() - .unwrap() - .join("tari-universe") - .join("mmproxy"); + let working_dir = data_dir.join("mmproxy"); std::fs::create_dir_all(&working_dir)?; let args: Vec = vec![ "-b".to_string(), @@ -75,6 +76,10 @@ impl ProcessAdapter for MergeMiningProxyAdapter { .kill_on_drop(true) .spawn()?; + if let Some(id) = child.id() { + fs::write(data_dir.join("mmproxy_pid"), id.to_string())?; + } + select! { _res = shutdown_signal =>{ child.kill().await?; @@ -84,6 +89,13 @@ impl ProcessAdapter for MergeMiningProxyAdapter { dbg!("Exited badly:", res2?); }, }; + + match fs::remove_file(data_dir.join("mmproxy_pid")) { + Ok(_) => {} + Err(e) => { + warn!(target: LOG_TARGET, "Could not clear node's pid file"); + } + } Ok(()) })), }, @@ -94,6 +106,10 @@ impl ProcessAdapter for MergeMiningProxyAdapter { fn name(&self) -> &str { "minotari_merge_mining_proxy" } + + fn pid_file_name(&self) -> &str { + "mmproxy_pid" + } } pub struct MergeMiningProxyInstance { diff --git a/src-tauri/src/minotari_node_adapter.rs b/src-tauri/src/minotari_node_adapter.rs index 209a06eb9..8f5f66863 100644 --- a/src-tauri/src/minotari_node_adapter.rs +++ b/src-tauri/src/minotari_node_adapter.rs @@ -1,15 +1,17 @@ use crate::binary_resolver::{Binaries, BinaryResolver}; use crate::node_manager::NodeIdentity; use crate::process_adapter::{ProcessAdapter, ProcessInstance, StatusMonitor}; +use crate::process_killer::kill_process; use crate::xmrig_adapter::XmrigInstance; use anyhow::{anyhow, Error}; use async_trait::async_trait; use dirs_next::data_local_dir; -use log::info; +use log::{info, warn}; use minotari_node_grpc_client::grpc::{ Empty, GetHeaderByHashRequest, HeightRequest, NewBlockTemplateRequest, PowAlgo, }; use minotari_node_grpc_client::BaseNodeGrpcClient; +use std::fs; use std::path::PathBuf; use tari_core::transactions::tari_amount::MicroMinotari; use tari_crypto::ristretto::RistrettoPublicKey; @@ -42,14 +44,14 @@ impl ProcessAdapter for MinotariNodeAdapter { fn spawn_inner( &self, - _log_path: PathBuf, + data_dir: PathBuf, window: tauri::Window, ) -> Result<(Self::Instance, Self::StatusMonitor), Error> { let inner_shutdown = Shutdown::new(); let shutdown_signal = inner_shutdown.to_signal(); info!(target: LOG_TARGET, "Starting minotari node"); - let working_dir = data_local_dir().unwrap().join("tari-universe").join("node"); + let working_dir = data_dir.join("node"); std::fs::create_dir_all(&working_dir)?; let mut args: Vec = vec![ @@ -100,6 +102,10 @@ impl ProcessAdapter for MinotariNodeAdapter { .kill_on_drop(true) .spawn()?; + if let Some(id) = child.id() { + fs::write(data_dir.join("node_pid"), id.to_string())?; + } + select! { _res = shutdown_signal =>{ child.kill().await?; @@ -111,9 +117,12 @@ impl ProcessAdapter for MinotariNodeAdapter { }; println!("Stopping minotari node"); - // child.kill().await?; - // let out = child.wait_with_output().await?; - // println!("stdout: {}", String::from_utf8_lossy(&out.stdout)); + match fs::remove_file(data_dir.join("node_pid")) { + Ok(_) => {} + Err(e) => { + warn!(target: LOG_TARGET, "Could not clear node's pid file"); + } + } Ok(()) })), }, @@ -124,6 +133,10 @@ impl ProcessAdapter for MinotariNodeAdapter { fn name(&self) -> &str { "minotari_node" } + + fn pid_file_name(&self) -> &str { + "node_pid" + } } pub struct MinotariNodeInstance { diff --git a/src-tauri/src/process_adapter.rs b/src-tauri/src/process_adapter.rs index 787bbd997..d3338f84e 100644 --- a/src-tauri/src/process_adapter.rs +++ b/src-tauri/src/process_adapter.rs @@ -1,6 +1,12 @@ +use crate::process_killer::kill_process; +use anyhow::Error; use async_trait::async_trait; +use log::warn; +use std::fs; use std::path::PathBuf; +const LOG_TARGET: &str = "tari::universe::process_adapter"; + pub trait ProcessAdapter { type Instance: ProcessInstance; type StatusMonitor: StatusMonitor; @@ -19,6 +25,21 @@ pub trait ProcessAdapter { ) -> Result<(Self::Instance, Self::StatusMonitor), anyhow::Error> { self.spawn_inner(base_folder, window) } + + fn pid_file_name(&self) -> &str; + + fn kill_previous_instances(&self, base_folder: PathBuf) -> Result<(), Error> { + match fs::read_to_string(base_folder.join(self.pid_file_name())) { + Ok(pid) => { + let pid = pid.trim().parse::()?; + kill_process(pid)?; + } + Err(e) => { + warn!(target: LOG_TARGET, "Could not read node's pid file: {}", e); + } + } + Ok(()) + } } pub trait StatusMonitor { diff --git a/src-tauri/src/process_killer.rs b/src-tauri/src/process_killer.rs new file mode 100644 index 000000000..835b4c095 --- /dev/null +++ b/src-tauri/src/process_killer.rs @@ -0,0 +1,16 @@ +use std::process::Command; + +pub fn kill_process(pid: u32) -> Result<(), anyhow::Error> { + if cfg!(target_os = "windows") { + let _ = Command::new("taskkill") + .args(&["/F", "/PID", &pid.to_string()]) + .output()?; + } else { + use nix::sys::signal::{self, Signal}; + use nix::unistd::Pid; + + let pid = Pid::from_raw(pid as i32); + signal::kill(pid, Signal::SIGTERM); + } + Ok(()) +} diff --git a/src-tauri/src/process_watcher.rs b/src-tauri/src/process_watcher.rs index e6442f0e3..cd3ad421d 100644 --- a/src-tauri/src/process_watcher.rs +++ b/src-tauri/src/process_watcher.rs @@ -29,6 +29,14 @@ impl ProcessWatcher { } impl ProcessWatcher { + pub async fn kill_previous_instances( + &mut self, + base_path: PathBuf, + ) -> Result<(), anyhow::Error> { + self.adapter.kill_previous_instances(base_path)?; + Ok(()) + } + pub async fn start( &mut self, app_shutdown: ShutdownSignal, @@ -40,6 +48,8 @@ impl ProcessWatcher { println!("Tried to start process watcher for {} twice", name); return Ok(()); } + info!(target: LOG_TARGET, "Starting process watcher for {}", name); + self.kill_previous_instances(base_path.clone()).await?; self.internal_shutdown = Shutdown::new(); let mut inner_shutdown = self.internal_shutdown.to_signal(); diff --git a/src-tauri/src/wallet_adapter.rs b/src-tauri/src/wallet_adapter.rs index 7c6a46824..4817b0cd4 100644 --- a/src-tauri/src/wallet_adapter.rs +++ b/src-tauri/src/wallet_adapter.rs @@ -5,11 +5,12 @@ use crate::process_adapter::{ProcessAdapter, ProcessInstance, StatusMonitor}; use anyhow::{anyhow, Error}; use async_trait::async_trait; use dirs_next::data_local_dir; -use log::info; +use log::{info, warn}; use minotari_node_grpc_client::grpc::wallet_client::WalletClient; use minotari_node_grpc_client::grpc::{Empty, GetBalanceRequest}; use minotari_node_grpc_client::BaseNodeGrpcClient; use serde::Serialize; +use std::fs; use std::path::PathBuf; use tari_core::transactions::tari_amount::MicroMinotari; use tari_crypto::ristretto::RistrettoPublicKey; @@ -46,7 +47,7 @@ impl ProcessAdapter for WalletAdapter { type StatusMonitor = WalletStatusMonitor; fn spawn_inner( &self, - _log_path: PathBuf, + data_dir: PathBuf, window: tauri::Window, ) -> Result<(Self::Instance, Self::StatusMonitor), Error> { // TODO: This was copied from node_adapter. This should be DRY'ed up @@ -54,10 +55,7 @@ impl ProcessAdapter for WalletAdapter { let shutdown_signal = inner_shutdown.to_signal(); info!(target: LOG_TARGET, "Starting read only wallet"); - let working_dir = data_local_dir() - .unwrap() - .join("tari-universe") - .join("wallet"); + let working_dir = data_dir.join("wallet"); std::fs::create_dir_all(&working_dir)?; let mut args: Vec = vec![ @@ -119,6 +117,10 @@ impl ProcessAdapter for WalletAdapter { .kill_on_drop(true) .spawn()?; + if let Some(id) = child.id() { + std::fs::write(data_dir.join("wallet_pid"), id.to_string())?; + } + select! { _res = shutdown_signal =>{ child.kill().await?; @@ -129,10 +131,12 @@ impl ProcessAdapter for WalletAdapter { }, }; println!("Stopping minotari node"); - - // child.kill().await?; - // let out = child.wait_with_output().await?; - // println!("stdout: {}", String::from_utf8_lossy(&out.stdout)); + match fs::remove_file(data_dir.join("wallet_pid")) { + Ok(_) => {} + Err(e) => { + warn!(target: LOG_TARGET, "Could not clear node's pid file"); + } + } Ok(()) })), }, @@ -143,6 +147,10 @@ impl ProcessAdapter for WalletAdapter { fn name(&self) -> &str { "wallet" } + + fn pid_file_name(&self) -> &str { + "wallet_pid" + } } pub struct WalletInstance { diff --git a/src-tauri/src/xmrig/latest_release.rs b/src-tauri/src/xmrig/latest_release.rs index 9ec6ea515..58c964725 100644 --- a/src-tauri/src/xmrig/latest_release.rs +++ b/src-tauri/src/xmrig/latest_release.rs @@ -22,16 +22,10 @@ pub struct XmrigRelease { } impl XmrigRelease { - pub fn get_asset(&self, os: &str) -> Option<&Asset> { + pub fn get_asset(&self, id: &str) -> Option<&Asset> { for asset in &self.assets { info!(target: LOG_TARGET, "Checking asset {:?}", asset); - // macos-arm64 doesn't have an os field for some reason - if asset.os.is_none() { - if asset.id == os { - return Some(asset); - } - } - if asset.os.as_deref() == Some(os) { + if asset.id == id { return Some(asset); } } diff --git a/src-tauri/src/xmrig_adapter.rs b/src-tauri/src/xmrig_adapter.rs index 3314f3c1b..26cd41abe 100644 --- a/src-tauri/src/xmrig_adapter.rs +++ b/src-tauri/src/xmrig_adapter.rs @@ -1,9 +1,10 @@ use crate::cpu_miner::CpuMinerEvent; use crate::download_utils::{download_file, extract}; +use crate::process_killer::kill_process; use crate::xmrig::http_api::XmrigHttpApiClient; use crate::xmrig::latest_release::fetch_latest_release; use anyhow::Error; -use log::info; +use log::{info, warn}; use std::path::PathBuf; use tari_shutdown::Shutdown; use tokio::fs; @@ -61,17 +62,19 @@ impl XmrigAdapter { } pub fn spawn( &self, + cache_dir: PathBuf, + logs_dir: PathBuf, + data_dir: PathBuf, window: tauri::Window, ) -> Result<(Receiver, XmrigInstance, XmrigHttpApiClient), anyhow::Error> { + self.kill_previous_instances(data_dir.clone())?; + let (_tx, rx) = tokio::sync::mpsc::channel(100); - let cache_dir = tauri::api::path::cache_dir() - .ok_or(anyhow::anyhow!("Failed to get cache dir"))? - .join("tari-universe"); let force_download = self.force_download; let xmrig_shutdown = Shutdown::new(); let mut shutdown_signal = xmrig_shutdown.to_signal(); let mut args = self.node_connection.generate_args(); - let xmrig_log_file = cache_dir.join("log").join("xmrig.log"); + let xmrig_log_file = logs_dir.join("xmrig.log"); std::fs::create_dir_all(xmrig_log_file.parent().unwrap())?; args.push(format!("--log-file={}", &xmrig_log_file.to_str().unwrap())); args.push(format!("--http-port={}", self.http_api_port)); @@ -100,23 +103,24 @@ impl XmrigAdapter { let xmrig_bin = xmrig_dir.join("xmrig"); let mut xmrig = tokio::process::Command::new(xmrig_bin) .args(args) - // TODO: IF you uncomment these, then it will capture the output to mem. Not sure if that is better or worse - // than outputing it immediately - // .stdout(std::process::Stdio::piped()) - // .stderr(std::process::Stdio::piped()) .kill_on_drop(true) .spawn()?; - // let (receiver, xmrig) = - // tauri::api::process::Command::new(xmrig_bin.to_str().unwrap().to_string()) - // .current_dir(xmrig_dir) - // .spawn()?; - // TODO: Try use an either here + if let Some(id) = xmrig.id() { + std::fs::write(data_dir.join("xmrig_pid"), id.to_string())?; + } shutdown_signal.wait().await; println!("Stopping xmrig"); xmrig.kill().await?; + match std::fs::remove_file(data_dir.join("xmrig_pid")) { + Ok(_) => {} + Err(e) => { + warn!(target: LOG_TARGET, "Could not clear xmrig's pid file"); + } + } + Ok(()) })), }, @@ -129,11 +133,9 @@ impl XmrigAdapter { force_download: bool, window: tauri::Window, ) -> Result { + dbg!(&cache_dir); let latest_release = fetch_latest_release().await?; - let xmrig_dir = cache_dir - .join("com.tari.universe") - .join("xmrig") - .join(&latest_release.version); + let xmrig_dir = cache_dir.join("xmrig").join(&latest_release.version); if force_download { println!("Cleaning up xmrig dir"); let _ = fs::remove_dir_all(&xmrig_dir).await; @@ -141,10 +143,7 @@ impl XmrigAdapter { if !xmrig_dir.exists() { println!("Latest version of xmrig doesn't exist"); println!("latest version is {}", latest_release.version); - let in_progress_dir = cache_dir - .join("com.tari.universe") - .join("xmrig") - .join("in_progress"); + let in_progress_dir = cache_dir.join("xmrig").join("in_progress"); if in_progress_dir.exists() { println!("Trying to delete dir {:?}", in_progress_dir); match fs::remove_dir(&in_progress_dir).await { @@ -156,10 +155,10 @@ impl XmrigAdapter { } } - let os_string = get_os_string(); - info!(target: LOG_TARGET, "Downloading xmrig for {}", &os_string); + let id = get_os_string_id(); + info!(target: LOG_TARGET, "Downloading xmrig for {}", &id); let platform = latest_release - .get_asset(&os_string) + .get_asset(&id) .ok_or(anyhow::anyhow!("Failed to get platform asset"))?; println!("Downloading file"); println!("Downloading file from {}", &platform.url); @@ -174,6 +173,19 @@ impl XmrigAdapter { } Ok(latest_release.version) } + + fn kill_previous_instances(&self, base_folder: PathBuf) -> Result<(), Error> { + match std::fs::read_to_string(base_folder.join("xmrig_pid")) { + Ok(pid) => { + let pid = pid.trim().parse::()?; + kill_process(pid)?; + } + Err(e) => { + warn!(target: LOG_TARGET, "Could not read xmrigs pid file: {}", e); + } + } + Ok(()) + } } impl XmrigInstance { @@ -209,10 +221,10 @@ impl Drop for XmrigInstance { } #[allow(unreachable_code)] -fn get_os_string() -> String { +fn get_os_string_id() -> String { #[cfg(target_os = "windows")] { - return "windows-x64".to_string(); + return "msvc-win64".to_string(); } #[cfg(target_os = "macos")] @@ -232,12 +244,12 @@ fn get_os_string() -> String { #[cfg(target_os = "linux")] { - return "linux-x64".to_string(); + return "linux-static-x64".to_string(); } #[cfg(target_os = "freebsd")] { - return "freebsd-x64".to_string(); + return "freebsd-static-x64".to_string(); } panic!("Unsupported OS"); diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index f501f6ebc..30769d92f 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -7,7 +7,7 @@ }, "package": { "productName": "Tari Universe", - "version": "0.1.20" + "version": "0.1.21" }, "tauri": { "updater": { diff --git a/src/App.tsx b/src/App.tsx index 94ed892f9..c912f5a60 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,24 +1,26 @@ import './theme/theme.css'; -import { useEffect, useRef } from 'react'; -import { invoke } from '@tauri-apps/api/tauri'; +import {useEffect, useRef} from 'react'; +import {invoke} from '@tauri-apps/api/tauri'; import CssBaseline from '@mui/material/CssBaseline'; -import { ThemeProvider } from '@mui/material/styles'; -import { lightTheme } from './theme/themes'; -import { ContainerInner, DashboardContainer } from './theme/styles'; -import { SideBar } from './containers/SideBar'; -import { Dashboard } from './containers/Dashboard'; -import { TitleBar } from './containers/TitleBar'; -import { AppBackground } from './containers/AppBackground'; +import {ThemeProvider} from '@mui/material/styles'; +import {lightTheme} from './theme/themes'; +import {ContainerInner, DashboardContainer} from './theme/styles'; +import {SideBar} from './containers/SideBar'; +import {Dashboard} from './containers/Dashboard'; +import {TitleBar} from './containers/TitleBar'; +import {AppBackground} from './containers/AppBackground'; import ErrorSnackbar from './containers/Error/ErrorSnackbar'; -import { useUIStore } from './store/useUIStore.ts'; -import { useGetStatus } from './hooks/useGetStatus.ts'; -import { listen } from '@tauri-apps/api/event'; -import { TauriEvent } from './types.ts'; +import {useUIStore} from './store/useUIStore.ts'; +import {useGetStatus} from './hooks/useGetStatus.ts'; +import {listen} from '@tauri-apps/api/event'; +import {TauriEvent} from './types.ts'; import useAppStateStore from './store/appStateStore.ts'; function App() { const background = useUIStore((s) => s.background); const view = useUIStore((s) => s.view); + const setView = useUIStore((s) => s.setView); + const setBackground = useUIStore((s) => s.setBackground); const startupInitiated = useRef(false); const setSetupDetails = useAppStateStore((s) => s.setSetupDetails); const settingUpFinished = useAppStateStore((s) => s.settingUpFinished); @@ -26,13 +28,15 @@ function App() { useEffect(() => { const unlistenPromise = listen( 'message', - ({ event, payload }: TauriEvent) => { + ({event, payload}: TauriEvent) => { console.log('Event:', event, payload); switch (payload.event_type) { case 'setup_status': setSetupDetails(payload.title, payload.progress); if (payload.progress >= 1.0) { settingUpFinished(); + setView("mining"); + setBackground("mining"); } break; default: @@ -45,10 +49,14 @@ function App() { } ); if (!startupInitiated.current) { - invoke('setup_application').then((r) => { - console.log(r); - startupInitiated.current = true; + startupInitiated.current = true; + setView("setup"); + setBackground("onboarding"); + invoke('setup_application').catch((e) => { + console.error('Failed to setup application:', e); + }); + } return () => { @@ -60,17 +68,17 @@ function App() { return ( - + - + - - + + - + ); } diff --git a/src/assets/setup.png b/src/assets/setup.png index 76935a6cd..e3feb00ba 100644 Binary files a/src/assets/setup.png and b/src/assets/setup.png differ diff --git a/src/containers/Dashboard/SetupView/SetupView.tsx b/src/containers/Dashboard/SetupView/SetupView.tsx index f525974fc..421b91cc5 100644 --- a/src/containers/Dashboard/SetupView/SetupView.tsx +++ b/src/containers/Dashboard/SetupView/SetupView.tsx @@ -3,13 +3,23 @@ import { Stack, Typography } from '@mui/material'; import { StyledLinearProgress, ProgressBox } from '../styles'; import VisualMode from '../components/VisualMode'; -function SetupView({ title, progressPercentage }: { title: string, progressPercentage: number }) { +function SetupView({ + title, + progressPercentage, +}: { + title: string; + progressPercentage: number; +}) { return ( - Setup + Setup{' '} - Setting up the Tari truth machine... + Setting up the Tari truth machine... This might take a few minutes. @@ -17,7 +27,10 @@ function SetupView({ title, progressPercentage }: { title: string, progressPerce Don’t worry you’ll only need to do this once. - + {`${progressPercentage}% - ${title}`} diff --git a/src/containers/SideBar/TestButtons.tsx b/src/containers/SideBar/TestButtons.tsx index 50c0c2f7b..5bc453a1c 100644 --- a/src/containers/SideBar/TestButtons.tsx +++ b/src/containers/SideBar/TestButtons.tsx @@ -14,7 +14,10 @@ function TestButtons() { const handleSetView = (value: viewType) => { setView(value); setSelectedView(value); - if (value === 'setup' || value === 'tribes') { + if (value === 'setup') { + setBackground('onboarding'); + } + if (value === 'tribes') { setBackground('loading'); } if (value === 'mining') { @@ -22,6 +25,11 @@ function TestButtons() { } }; + // const handleSetStatus = (value: backgroundType) => { + // setBackground(value); + // setSelectedBg(value); + // }; + return ( For testing: diff --git a/src/containers/SideBar/components/Wallet.tsx b/src/containers/SideBar/components/Wallet.tsx index d941409a1..1394b4053 100644 --- a/src/containers/SideBar/components/Wallet.tsx +++ b/src/containers/SideBar/components/Wallet.tsx @@ -1,6 +1,6 @@ -import { Typography, Stack, Divider } from '@mui/material'; +import { Typography, Stack } from '@mui/material'; import { ThemeProvider } from '@mui/material/styles'; -import { WalletContainer, Handle, HoverStack, WalletButton } from '../styles'; +import { WalletContainer, Handle } from '../styles'; import { darkTheme } from '../../../theme/themes'; import { AddressBox, BalanceChangeChip } from '../styles'; import { FaCircleArrowUp } from 'react-icons/fa6'; @@ -93,35 +93,6 @@ function Wallet() { /> - - } - style={{ - borderTop: '1px solid rgba(255,255,255,0.1)', - marginTop: '10px', - paddingTop: '10px', - width: '100%', - }} - > - console.log('Send')} - > - Send - - console.log('Receive')} - > - Receive - - - );