diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index 26ddc4382..4f753f03d 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -70,4 +70,4 @@ rand = "0.8.5"
custom-protocol = ["tauri/custom-protocol"]
[package.metadata.cargo-machete]
-ignored = ["log4rs", "xz2"]
+ignored = ["log4rs", "xz2", "libsqlite3-sys", "minotari_wallet_grpc_client"]
diff --git a/src-tauri/src/cpu_miner.rs b/src-tauri/src/cpu_miner.rs
index 3d386c96f..4125fa768 100644
--- a/src-tauri/src/cpu_miner.rs
+++ b/src-tauri/src/cpu_miner.rs
@@ -151,11 +151,7 @@ impl CpuMiner {
// Refresh CPUs again.
s.refresh_cpu_all();
- let mut cpu_brand = "Unknown";
- for cpu in s.cpus() {
- cpu_brand = cpu.brand();
- break;
- }
+ let cpu_brand = s.cpus().get(0).map(|cpu| cpu.brand()).unwrap_or("Unknown");
let cpu_usage = s.global_cpu_usage() as u32;
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index a71475550..dbf0b538b 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -25,25 +25,43 @@ use crate::mm_proxy_manager::MmProxyManager;
use crate::node_manager::NodeManager;
use crate::wallet_adapter::WalletBalance;
use crate::wallet_manager::WalletManager;
-use dirs_next::data_dir;
-use futures_util::{FutureExt, TryFutureExt};
+use futures_util::TryFutureExt;
use log::{debug, error, info, warn};
-use serde::Serialize;
+use serde::{Deserialize, Serialize};
use std::sync::Arc;
use std::thread::sleep;
use std::{panic, process};
use tari_common_types::tari_address::TariAddress;
use tari_core::transactions::tari_amount::MicroMinotari;
use tari_shutdown::Shutdown;
-use tauri::{api, RunEvent, UpdaterEvent};
+use tauri::{RunEvent, UpdaterEvent};
use tokio::sync::RwLock;
-use tokio::{join, try_join};
+use tokio::try_join;
+
+use std::thread;
+use std::time::Duration;
+
+#[derive(Debug, Serialize, Deserialize, Clone)]
+struct SetupStatusEvent {
+ event_type: String,
+ title: String,
+ progress: f64,
+}
#[tauri::command]
-async fn init<'r>(
+async fn setup_application<'r>(
+ window: tauri::Window,
state: tauri::State<'r, UniverseAppState>,
app: tauri::AppHandle,
) -> Result<(), String> {
+ let _ = window.emit(
+ "message",
+ SetupStatusEvent {
+ event_type: "setup_status".to_string(),
+ title: "Downloading Applications".to_string(),
+ progress: 0.5,
+ },
+ );
let data_dir = app.path_resolver().app_local_data_dir().unwrap();
let task1 = state
.node_manager
@@ -62,6 +80,16 @@ async fn init<'r>(
});
try_join!(task1, task2)?;
+ _ = window.emit(
+ "message",
+ SetupStatusEvent {
+ event_type: "setup_status".to_string(),
+ title: "Syncing Blockchain".to_string(),
+ progress: 1.0,
+ },
+ );
+ // TODO: Sync blockchain when p2p mining finished
+ thread::sleep(Duration::from_secs(5));
Ok(())
}
@@ -293,7 +321,7 @@ fn main() {
}
})
.invoke_handler(tauri::generate_handler![
- init,
+ setup_application,
status,
start_mining,
stop_mining
diff --git a/src-tauri/src/minotari_node_adapter.rs b/src-tauri/src/minotari_node_adapter.rs
index f11f8b2d1..2337eedcb 100644
--- a/src-tauri/src/minotari_node_adapter.rs
+++ b/src-tauri/src/minotari_node_adapter.rs
@@ -197,7 +197,7 @@ impl MinotariNodeStatusMonitor {
})
.await?;
let mut res = res.into_inner();
- while let Some(difficulty) = res.message().await? {
+ if let Some(difficulty) = res.message().await? {
return Ok((
difficulty.sha3x_estimated_hash_rate,
difficulty.randomx_estimated_hash_rate,
diff --git a/src/App.tsx b/src/App.tsx
index bbae085d6..5ada2b549 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -14,57 +14,66 @@ import useAppStateStore from './store/appStateStore';
import ErrorSnackbar from './containers/Error/ErrorSnackbar';
function App() {
- const {
- view, background, setHashRate, setCpuUsage, setAppState, setError,
- setCpuBrand, setEstimatedEarnings,
- setBlockHeight, setBlockTime, setIsSynced, setWallet
- } =
- useAppStateStore((state) => ({
- view: state.view,
- background: state.background,
- setHashRate: state.setHashRate,
- setCpuUsage: state.setCpuUsage,
- setAppState: state.setAppState,
- setError: state.setError,
- setCpuBrand: state.setCpuBrand,
- setEstimatedEarnings: state.setEstimatedEarnings,
- setBlockHeight: state.setBlockHeight,
- setBlockTime: state.setBlockTime,
- setIsSynced: state.setIsSynced,
- setWallet: state.setWallet
- }));
+ const { view, background, setHashRate, setCpuUsage, setAppState, setError,
+ setCpuBrand, setEstimatedEarnings, setBlockHeight, setBlockTime, setIsSynced,
+ settingUpFinished, setSetupDetails, setWallet
+ } =
+ useAppStateStore((state) => ({
+ view: state.view,
+ background: state.background,
+ isSettingUp: state.isSettingUp,
+ setHashRate: state.setHashRate,
+ setCpuUsage: state.setCpuUsage,
+ setAppState: state.setAppState,
+ setError: state.setError,
+ setCpuBrand: state.setCpuBrand,
+ setEstimatedEarnings: state.setEstimatedEarnings,
+ settingUpFinished: state.settingUpFinished,
+ setSetupDetails: state.setSetupDetails,
+ setBlockHeight: state.setBlockHeight,
+ setBlockTime: state.setBlockTime,
+ setIsSynced: state.setIsSynced,
+ setWallet: state.setWallet,
+ }));
- useEffect(() => {
- invoke("init", {}).catch((e) => {
- console.error('Could not init', e);
- setError(e.toString());
- });
- const unlistenPromise = listen('message', (event) => {
- console.log('some kind of event', event.event, event.payload);
- });
+ useEffect(() => {
+ const unlistenPromise = listen('message', ({ event, payload }: TauriEvent) => {
+ console.log('some kind of event', event, payload);
+
+ switch (payload.event_type) {
+ case "setup_status":
+ setSetupDetails(payload.title, payload.progress);
+ break;
+ default:
+ console.log("Unknown tauri event: ", { event, payload });
+ break;
+ }
+ });
- const intervalId = setInterval(() => {
- invoke('status', {})
- .then((status: any) => {
- console.log('Status', status);
- setAppState(status);
- setCpuUsage(status.cpu?.cpu_usage);
- setHashRate(status.cpu?.hash_rate);
- setCpuBrand(status.cpu?.cpu_brand);
- setEstimatedEarnings(status.cpu?.estimated_earnings);
- setBlockHeight(status.base_node?.block_height);
- setBlockTime(status.base_node?.block_time);
- setIsSynced(status.base_node?.is_synced);
- setWallet({balance: status.wallet_balance?.available_balance + status.wallet_balance?.timelocked_balance + status.wallet_balance?.pending_incoming_balance});
- })
- .catch((e) => {
- console.error('Could not get status', e);
- setError(e.toString());
- });
+ invoke('setup_application').then(() => settingUpFinished());
+
+ const intervalId = setInterval(() => {
+ invoke('status', {})
+ .then((status: any) => {
+ console.log('Status', status);
+ setAppState(status);
+ setCpuUsage(status.cpu?.cpu_usage);
+ setHashRate(status.cpu?.hash_rate);
+ setCpuBrand(status.cpu?.cpu_brand);
+ setEstimatedEarnings(status.cpu?.estimated_earnings);
+ setBlockHeight(status.base_node?.block_height);
+ setBlockTime(status.base_node?.block_time);
+ setIsSynced(status.base_node?.is_synced);
+ setWallet({balance: status.wallet_balance?.available_balance + status.wallet_balance?.timelocked_balance + status.wallet_balance?.pending_incoming_balance});
+ })
+ .catch((e) => {
+ console.error('Could not get status', e);
+ setError(e.toString());
+ });
}, 1000);
return () => {
- unlistenPromise.then((unlisten) => unlisten());
- clearInterval(intervalId);
+ unlistenPromise.then((unlisten) => unlisten());
+ clearInterval(intervalId);
};
}, []);
diff --git a/src/containers/Dashboard/Dashboard.tsx b/src/containers/Dashboard/Dashboard.tsx
index 754befdd5..2172cc02a 100644
--- a/src/containers/Dashboard/Dashboard.tsx
+++ b/src/containers/Dashboard/Dashboard.tsx
@@ -1,15 +1,15 @@
import { DashboardContainer } from './styles';
import MiningView from './MiningView/MiningView';
-import SetupView from './SetupView/SetupView';
import TribesView from './TribesView/TribesView';
import { viewType } from '../../store/types';
+import SetupViewContainer from './SetupView/SetupViewContainer';
function Dashboard({ status }: { status: viewType }) {
let view = ;
switch (status) {
case 'setup':
- view = ;
+ view = ;
break;
case 'tribes':
view = ;
diff --git a/src/containers/Dashboard/SetupView/SetupView.tsx b/src/containers/Dashboard/SetupView/SetupView.tsx
index 1fcae309b..f525974fc 100644
--- a/src/containers/Dashboard/SetupView/SetupView.tsx
+++ b/src/containers/Dashboard/SetupView/SetupView.tsx
@@ -3,14 +3,13 @@ import { Stack, Typography } from '@mui/material';
import { StyledLinearProgress, ProgressBox } from '../styles';
import VisualMode from '../components/VisualMode';
-function SetupView() {
- const progress = 30;
+function SetupView({ title, progressPercentage }: { title: string, progressPercentage: number }) {
return (
- Setting up the Tari truth machine...
+ Setting up the Tari truth machine...
This might take a few minutes.
@@ -18,9 +17,9 @@ function SetupView() {
Don’t worry you’ll only need to do this once.
-
+
- {progress}%
+ {`${progressPercentage}% - ${title}`}
diff --git a/src/containers/Dashboard/SetupView/SetupViewContainer.tsx b/src/containers/Dashboard/SetupView/SetupViewContainer.tsx
new file mode 100644
index 000000000..86dc76045
--- /dev/null
+++ b/src/containers/Dashboard/SetupView/SetupViewContainer.tsx
@@ -0,0 +1,32 @@
+import { useEffect, useMemo } from "react";
+import useAppStateStore from "../../../store/appStateStore";
+import SetupView from "./SetupView";
+
+let latestSetupProgress = 0;
+
+function SetupViewContainer() {
+ const { setupTitle, setupProgress } = useAppStateStore((state) => ({
+ setupTitle: state.setupTitle,
+ setupProgress: state.setupProgress,
+ }));
+ const progressPercentage = useMemo(
+ () => Math.floor(latestSetupProgress * 100),
+ [latestSetupProgress]
+ );
+
+ useEffect(() => {
+ const progressInterval = setInterval(() => {
+ latestSetupProgress += (setupProgress - latestSetupProgress) * 0.25;
+ }, 500);
+
+ return () => {
+ clearInterval(progressInterval);
+ };
+ }, [setupProgress]);
+
+ return (
+
+ );
+}
+
+export default SetupViewContainer;
diff --git a/src/store/appStateStore.ts b/src/store/appStateStore.ts
index 352510347..f580b9c7e 100644
--- a/src/store/appStateStore.ts
+++ b/src/store/appStateStore.ts
@@ -3,115 +3,137 @@ import {invoke} from '@tauri-apps/api/tauri';
import {viewType, backgroundType, modeType} from './types';
interface AppState {
- appState: any;
- setAppState: (value: any) => void;
- error: string;
- setError: (value: string) => void;
- topStatus: string;
- setTopStatus: (value: string) => void;
- errorOpen: boolean;
- setErrorOpen: (value: boolean) => void;
+ appState: any;
+ setAppState: (value: any) => void;
+ error: string;
+ setError: (value: string) => void;
+ topStatus: string;
+ setTopStatus: (value: string) => void;
+ errorOpen: boolean;
+ setErrorOpen: (value: boolean) => void;
+ setupTitle: string;
+ setupProgress: number;
+ setSetupDetails: (setupTitle: string, setupProgress: number) => void;
- // gui
- background: backgroundType;
- setBackground: (value: backgroundType) => void;
- view: viewType;
- setView: (value: viewType) => void;
- visualMode: boolean;
- setVisualMode: (value: boolean) => void;
- wallet: {
- balance: number;
- };
- setWallet: (value: { balance: number }) => void;
- isMining: boolean;
- setIsMining: (value: boolean) => void;
- isAutoMining: boolean;
- setIsAutoMining: (value: boolean) => void;sidebarOpen: boolean;
- setSidebarOpen: (value: boolean) => void;
+ // gui
+ background: backgroundType;
+ setBackground: (value: backgroundType) => void;
+ view: viewType;
+ setView: (value: viewType) => void;
+ visualMode: boolean;
+ setVisualMode: (value: boolean) => void;
+ wallet: {
+ balance: number;
+ };
+ setWallet: (value: { balance: number }) => void;
+ isMining: boolean;
+ setIsMining: (value: boolean) => void;
+ isAutoMining: boolean;
+ setIsAutoMining: (value: boolean) => void;
+ sidebarOpen: boolean;
+ setSidebarOpen: (value: boolean) => void;
+ isSettingUp: boolean;
- // stats
- cpuUsage: number;
- setCpuUsage: (value: number) => void;
- mode: modeType;
- setMode: (value: modeType) => void;
- hashRate: number;
- setHashRate: (value: number) => void;
- cpuBrand: string,
- setCpuBrand: (value: string) => void;
- estimatedEarnings: number,
- setEstimatedEarnings: (value: number) => void;
+ // stats
+ cpuUsage: number;
+ setCpuUsage: (value: number) => void;
+ mode: modeType;
+ setMode: (value: modeType) => void;
+ hashRate: number;
+ setHashRate: (value: number) => void;
+ cpuBrand: string,
+ setCpuBrand: (value: string) => void;
+ estimatedEarnings: number,
+ setEstimatedEarnings: (value: number) => void;
- blockHeight: number,
- setBlockHeight: (value: number) => void;
+ blockHeight: number,
+ setBlockHeight: (value: number) => void;
blockTime: number,
- setBlockTime: (value: number) => void;
+ setBlockTime: (value: number) => void;
isSynced: boolean,
- setIsSynced: (value: boolean) => void;// functions
- startMining: () => Promise;
- stopMining: () => Promise;
+ setIsSynced: (value: boolean) => void;
+ // functions
+ startMining: () => Promise;
+ stopMining: () => Promise;
+ settingUpFinished: () => Promise;
}
const useAppStateStore = create((set) => ({
- appState: {},
- setAppState: (value) => set({appState: value}),
- error: '',
- setError: (value) => set({error: value}),
- topStatus: 'Not mining',
- setTopStatus: (value) => set({topStatus: value}),
- errorOpen: false,
- setErrorOpen: (value) => set({errorOpen: value}),
+ appState: {},
+ setAppState: (value) => set({appState: value}),
+ error: '',
+ setError: (value) => set({error: value}),
+ topStatus: 'Not mining',
+ setTopStatus: (value) => set({topStatus: value}),
+ errorOpen: false,
+ setErrorOpen: (value) => set({errorOpen: value}),
- // gui
- background: 'idle',
- setBackground: (value) => set({background: value}),
- view: 'mining',
- setView: (value) => set({view: value}),
- visualMode: true,
- setVisualMode: (value) => set({visualMode: value}),
- wallet: {
- balance: 0
- },
- setWallet: (value) => set({wallet: value}),
- isMining: false,
- setIsMining: (value) => set({isMining: value}),
- isAutoMining: false,
- setIsAutoMining: (value) => set({ isAutoMining: value }),sidebarOpen: false,
- setSidebarOpen: (value) => set({sidebarOpen: value}),
+ // gui
+ background: 'loading',
+ setBackground: (value) => set({ background: value }),
+ view: 'setup',
+ setView: (value) => set({ view: value }),
+ visualMode: true,
+ setVisualMode: (value) => set({ visualMode: value }),
+ wallet: {
+ balance: 0,
+ },
+ setWallet: (value) => set({ wallet: value }),
+ isMining: false,
+ setIsMining: (value) => set({ isMining: value }),
+ isAutoMining: false,
+ setIsAutoMining: (value) => set({ isAutoMining: value }),
+ sidebarOpen: false,
+ setSidebarOpen: (value) => set({ sidebarOpen: value }),
+ isSettingUp: true,
+ setupTitle: "",
+ setupProgress: 0,
+ setSetupDetails: (setupTitle: string, setupProgress: number) => set({ setupTitle, setupProgress }),
- // stats
- cpuUsage: 0,
- setCpuUsage: (value) => set({cpuUsage: value}),
- mode: 'eco',
- setMode: (value) => set({mode: value}),
- hashRate: 0,
- setHashRate: (value) => set({hashRate: value}),
- cpuBrand: '',
- setCpuBrand: (value) => set({cpuBrand: value}),
- estimatedEarnings: 0,
- setEstimatedEarnings: (value) => set({estimatedEarnings: value}),
+ // stats
+ cpuUsage: 0,
+ setCpuUsage: (value) => set({cpuUsage: value}),
+ mode: 'eco',
+ setMode: (value) => set({mode: value}),
+ hashRate: 0,
+ setHashRate: (value) => set({hashRate: value}),
+ cpuBrand: '',
+ setCpuBrand: (value) => set({cpuBrand: value}),
+ estimatedEarnings: 0,
+ setEstimatedEarnings: (value) => set({estimatedEarnings: value}),
- blockHeight: 0,
- setBlockHeight: (value) => set({ blockHeight: value }),
- blockTime: 0,
- setBlockTime: (value) => set({ blockTime: value }),
- isSynced: false,
- setIsSynced: (value) => set({ isSynced: value }),// functions
- startMining: async () => {
- try {
- await invoke('start_mining', {});
- console.log('Mining started');
- } catch (e) {
- console.error('Could not start mining', e);
- }
- },
- stopMining: async () => {
- try {
- await invoke('stop_mining', {});
- console.log('Mining stopped');
- } catch (e) {
- console.error('Could not stop mining', e);
- }
- },
+ blockHeight: 0,
+ setBlockHeight: (value) => set({ blockHeight: value }),
+ blockTime: 0,
+ setBlockTime: (value) => set({ blockTime: value }),
+ isSynced: false,
+ setIsSynced: (value) => set({ isSynced: value }),
+
+ // functions
+ settingUpFinished: async () => {
+ set({
+ isSettingUp: false,
+ view: "mining",
+ background: "idle"
+ });
+ },
+
+ startMining: async () => {
+ try {
+ await invoke('start_mining', {});
+ console.log('Mining started');
+ } catch (e) {
+ console.error('Could not start mining', e);
+ }
+ },
+ stopMining: async () => {
+ try {
+ await invoke('stop_mining', {});
+ console.log('Mining stopped');
+ } catch (e) {
+ console.error('Could not stop mining', e);
+ }
+ },
}));
export default useAppStateStore;
diff --git a/src/types.ts b/src/types.ts
new file mode 100644
index 000000000..910a7d18f
--- /dev/null
+++ b/src/types.ts
@@ -0,0 +1,12 @@
+// Use union type
+type TauriEventPayload =
+| {
+ event_type: "setup_status",
+ title: string,
+ progress: number,
+}
+
+type TauriEvent = {
+ event: string;
+ payload: TauriEventPayload;
+}