Skip to content

Commit

Permalink
fix: setup flow listeners | progress getting stuck (tari-project#1402)
Browse files Browse the repository at this point in the history
Description
---
- ~~moved gl app logic out of `index.html` (-> `visuals.ts`) & actually
remove canvas entirely when toggling visual mode, instead of just hiding
it~~ moving to separate PR
- moved the Visual Mode toggle out of 'Experimental' Settings to General
Settings
- removed the listener for `frontend_ready` from RunEvent:Ready and used
`.on_page_load` instead, including the tauri state value of
`is_setup_finished` so we can skip the setup screens on the frontend if
that's already done and the `setup_message` events won't be emitted
again
- also added `ProgressTracker`'s `.send_last_action` in there so if it
_is_ still setting up, we can continue on and show the actual progress
on the FE where it was before the restart/refresh
- adjusted `useAppStateStore` a bit so we don't start with a truly value
for the setup check (most of the file changes were amending the uses of
`isSettingUp` after changing that around, sorry!)

Main files with actual changes
---


- ~~items moved from
[`index.html`](https://github.com/tari-project/universe/pull/1402/files#diff-0eb547304658805aad788d320f10bf1f292797b5e6d745a3bf617584da017051)
to
[`src/visuals.ts`](https://github.com/tari-project/universe/pull/1402/files#diff-5f2854a948facaeb956b06299de2f47fd38733eb7cd85f5b6ed8edee49bf1fbb)
(minor additions in `src/visuals.ts`~~ moving to separate PR
-
[`src-tauri/main.rs`](https://github.com/tari-project/universe/pull/1402/files#diff-2f5e0a90d4195e9986f5e24928dce16b59a80a2cf30f7059b38d55bd7d1eff69)
- setup progress addition to
[`src/hooks/app/isAppReady.ts`](https://github.com/tari-project/universe/pull/1402/files#diff-95c4d89aef2e2cee2be8a93864b2975ff76cc54eacadb0a0ee8238ed54bca36a)
- ~~cleanups + preload animation in
[`src/hooks/app/useSetUp.ts`](https://github.com/tari-project/universe/pull/1402/files#diff-818735307e6ef43bcc35e6609d72a1580524718a151bf5cf8d4d192c46ef5a41)~~
moving to separate PR
- neatening and moved some actions out of the main store in
[`src/store/appStateStore.ts`](https://github.com/tari-project/universe/pull/1402/files#diff-0d2e757ebac18751f8a38695036dc9f6a8e005c6a2cd7915dc7cafe49a05c5f2)
so they can be used outside of hooks/don't need to be added as deps


Motivation and Context
---

tari-project#1400 + the issue of setup getting stuck either at 0% or 100%

How Has This Been Tested?
---

locally

doesn't get stuck on zero if there's a refresh for whatever reason
(likely crash + restarts in prod builds/auto update), and `setup_inner`
isn't triggered again because `is_setup_finished` is already true:


https://github.com/user-attachments/assets/bf812724-4742-4526-924e-94403f9cc597

refreshing/a reload after setup is complete goes straight to the main
view + ~~canvas is completely removed on visual mode toggle~~ (moving to
separate PR):


https://github.com/user-attachments/assets/52d00998-6069-4a2a-975b-eb4cf809e99d
  • Loading branch information
shanimal08 authored Jan 21, 2025
1 parent 1b79664 commit 086a6fb
Show file tree
Hide file tree
Showing 25 changed files with 132 additions and 125 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ dist-ssr
*.sln
*.sw?
src-tauri/gpu_status.json
vite-profile*

# Sentry Config File
.env.sentry-build-plugin
Expand Down
5 changes: 2 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,10 @@
}
</style>
</head>

<body>
<main>
<canvas id="canvas"></canvas>
<main id="main">
<div id="root"></div>
<canvas id="canvas"></canvas>
<script type="module" src="src/main.tsx"></script>
<script>
let time;
Expand Down
62 changes: 31 additions & 31 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ async fn setup_inner(
let w_move_handle = app.clone();
tauri::async_runtime::spawn(async move {
let app_state = w_move_handle.state::<UniverseAppState>().clone();
let mut interval = time::interval(Duration::from_secs(10));
let mut interval = time::interval(Duration::from_secs(5));
let mut shutdown_signal = app_state.shutdown.to_signal();

loop {
Expand Down Expand Up @@ -752,24 +752,6 @@ async fn setup_inner(
Ok(())
}

async fn listen_to_frontend_ready(app: tauri::AppHandle) -> Result<(), anyhow::Error> {
let app_handle = app.clone();
app_handle.once("frontend_ready", move |_event| {
info!(target: LOG_TARGET, "Frontend is ready");
let app_clone: tauri::AppHandle = app.clone();
tauri::async_runtime::spawn(async move {
time::sleep(Duration::from_secs(3)).await;
app_clone
.get_webview_window("main")
.expect("Could not get main window")
.emit("app_ready", ())
.expect("Could not emit event 'app_ready'");
});
});

Ok(())
}

#[derive(Clone)]
struct UniverseAppState {
stop_start_mutex: Arc<Mutex<()>>,
Expand Down Expand Up @@ -813,6 +795,11 @@ struct FEPayload {
token: String,
}

#[derive(Clone, serde::Serialize)]
struct SetupPayload {
setup_complete: bool,
}

#[allow(clippy::too_many_lines)]
fn main() {
let _unused = fix_path_env::fix();
Expand Down Expand Up @@ -911,9 +898,7 @@ fn main() {
cached_p2pool_connections: Arc::new(RwLock::new(None)),
cached_miner_metrics: Arc::new(RwLock::new(None)),
};

let app_state2 = app_state.clone();

let app_state_clone = app_state.clone();
let app = tauri::Builder::default()
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_sentry::init_with_no_injection(&client))
Expand Down Expand Up @@ -956,7 +941,7 @@ fn main() {
log4rs::init_raw_config(config).expect("Could not initialize logging");

// Do this after logging has started otherwise we can't actually see any errors
app.manage(app_state2);
app.manage(app_state_clone);
match app.cli().matches() {
Ok(matches) => {
if let Some(backup_path) = matches.args.get("import-backup") {
Expand Down Expand Up @@ -987,6 +972,7 @@ fn main() {
}
};


let token_state_clone = app.state::<UniverseAppState>().airdrop_access_token.clone();
let memory_state_clone = app.state::<UniverseAppState>().in_memory_config.clone();
app.listen("airdrop_token", move |event| {
Expand Down Expand Up @@ -1098,6 +1084,22 @@ fn main() {
}
}
})
.on_page_load(|webview, _ | {
info!(target: LOG_TARGET, "Frontend is ready");
let w = webview.clone();
tauri::async_runtime::spawn(async move {
let app_handle = w.app_handle();
let state = app_handle.state::<UniverseAppState>().clone();
let setup_complete_clone = state.is_setup_finished.read().await;
let value = *setup_complete_clone;

let prog = ProgressTracker::new(app_handle.clone(), None);
prog.send_last_action("".to_string()).await;

time::sleep(Duration::from_secs(3)).await;
app_handle.clone().emit("app_ready", SetupPayload { setup_complete:value }).expect("Could not emit event 'app_ready'");
});
})
.invoke_handler(tauri::generate_handler![
commands::close_splashscreen,
commands::download_and_start_installer,
Expand Down Expand Up @@ -1168,16 +1170,14 @@ fn main() {
"Starting Tari Universe version: {}",
app.package_info().version
);

app.run(move |app_handle, event| match event {
tauri::RunEvent::Ready => {
info!(target: LOG_TARGET, "App is ready");
let a = app_handle.clone();
let app_handle_clone = app_handle.clone();
tauri::async_runtime::spawn( async move {
let state = app_handle_clone.state::<UniverseAppState>().clone();
let _unused = listen_to_frontend_ready(app_handle_clone.clone()).await;
let _res = setup_inner(state, a.clone()).await
info!(target: LOG_TARGET, "RunEvent Ready");
let handle_clone = app_handle.clone();
tauri::async_runtime::spawn(async move {
let state = handle_clone.state::<UniverseAppState>().clone();
let _res = setup_inner(state, handle_clone.clone())
.await
.inspect_err(|e| error!(target: LOG_TARGET, "Could not setup app: {:?}", e));
});
}
Expand Down
13 changes: 6 additions & 7 deletions src/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,9 @@ import { useIsAppReady } from '@app/hooks/app/isAppReady.ts';
import Splashscreen from '@app/containers/phase/Splashscreen/Splashscreen.tsx';

export default function App() {
const isShuttingDown = useShuttingDown();
const isAppReady = useIsAppReady();
const isSettingUp = useAppStateStore((s) => s.isSettingUp);

const showSetup = isSettingUp && !isShuttingDown && isAppReady;

const isShuttingDown = useShuttingDown();
const isSettingUp = useAppStateStore((s) => !s.setupComplete);
const setError = useAppStateStore((s) => s.setError);
const setIsWebglNotSupported = useUIStore((s) => s.setIsWebglNotSupported);
const { t } = useTranslation('common', { useSuspense: false });
Expand All @@ -45,6 +42,8 @@ export default function App() {
}
}, [isShuttingDown, isSettingUp]);

const showSetup = isSettingUp && !isShuttingDown && isAppReady;

return (
<ThemeProvider>
<GlobalReset />
Expand All @@ -63,11 +62,11 @@ export default function App() {
<Splashscreen />
</AppContentContainer>
)}
{showSetup && (
{showSetup ? (
<AppContentContainer key="setup" initial="hidden">
<Setup />
</AppContentContainer>
)}
) : null}
{!isShuttingDown && !isSettingUp && isAppReady && (
<AppContentContainer key="main" initial="dashboardInitial">
<MainView />
Expand Down
6 changes: 0 additions & 6 deletions src/App/AppWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,11 @@ import setupLogger from '../utils/shared-logger.ts';
import useListenForCriticalProblem from '@app/hooks/useListenForCriticalProblem.tsx';
import { setMiningNetwork } from '@app/store/miningStoreActions.ts';
import App from './App.tsx';
import { emit } from '@tauri-apps/api/event';

// FOR ANYTHING THAT NEEDS TO BE INITIALISED

setupLogger();
async function emitReady() {
await emit('frontend_ready');
}
export default function AppWrapper() {
void emitReady();

useDetectMode();
useDisableRefresh();
useLangaugeResolver();
Expand Down
2 changes: 1 addition & 1 deletion src/components/ToastStack/ToastStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Inside, Wrapper } from './styles';

export const ToastStack = () => {
const { toasts } = useToastStore();
const { isSettingUp } = useAppStateStore();
const isSettingUp = useAppStateStore((s) => !s.setupComplete);
const [isHovered, setIsHovered] = useState(false);

const handleMouseEnter = () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { AnimatePresence } from 'framer-motion';

import VisualMode from '@app/containers/main/Dashboard/components/VisualMode';
import AppVersions from './AppVersions.tsx';
import DebugSettings from './DebugSettings.tsx';
import ExperimentalWarning from './ExperimentalWarning.tsx';
Expand All @@ -24,7 +23,6 @@ export const ExperimentalSettings = () => {
<TorMarkup />
<MonerodMarkup />
{isP2poolEnabled && <P2poolMarkup />}
<VisualMode />
</>
)}
</AnimatePresence>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ResetSettingsButton } from './ResetSettingsButton.tsx';
import StartApplicationOnBootSettings from './StartApplicationOnBootSettings.tsx';
import AutoUpdate from './AutoUpdate.tsx';
import PreReleaseSettings from './PreReleaseSettings.tsx';
import VisualMode from '@app/containers/main/Dashboard/components/VisualMode.tsx';

export const GeneralSettings = () => {
return (
Expand All @@ -17,6 +18,7 @@ export const GeneralSettings = () => {
<PreReleaseSettings />
<AirdropPermissionSettings />
<LanguageSettings />
<VisualMode />
<ThemeSettings />
<LogsSettings />
<SettingsGroupWrapper $advanced>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function CpuMiningSettings() {
const { t } = useTranslation(['settings'], { useSuspense: false });
const isCpuMiningEnabled = useAppConfigStore((s) => s.cpu_mining_enabled);
const setCpuMiningEnabled = useAppConfigStore((s) => s.setCpuMiningEnabled);
const isSettingUp = useAppStateStore((s) => s.isSettingUp);
const isSettingUp = useAppStateStore((s) => !s.setupComplete);

const handleCpuMiningEnabled = useCallback(async () => {
await setCpuMiningEnabled(!isCpuMiningEnabled);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { useMiningMetricsStore } from '@app/store/useMiningMetricsStore.ts';

const GpuDevices = () => {
const { t } = useTranslation(['common', 'settings'], { useSuspense: false });
const miningAllowed = useAppStateStore((s) => !s.isSettingUp);
const miningAllowed = useAppStateStore((s) => s.setupComplete);
const isCPUMining = useMiningMetricsStore((s) => s.cpu.mining.is_mining);
const isGPUMining = useMiningMetricsStore((s) => s.gpu.mining.is_mining);
const gpuDevices = useMiningMetricsStore((s) => s.gpu.hardware);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const GpuMiningMarkup = () => {
const { t } = useTranslation(['settings'], { useSuspense: false });
const setGpuMiningEnabled = useAppConfigStore((s) => s.setGpuMiningEnabled);
const isGpuMiningEnabled = useAppConfigStore((s) => s.gpu_mining_enabled);
const isSettingUp = useAppStateStore((s) => s.isSettingUp);
const isSettingUp = useAppStateStore((s) => !s.setupComplete);
const gpuDevicesHardware = useMiningMetricsStore((s) => s.gpu.hardware);

const isGPUMiningAvailable = useMemo(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const P2pMarkup = ({ setDisabledStats }: P2pMarkupProps) => {
const { t } = useTranslation(['common', 'settings'], { useSuspense: false });
const isP2poolEnabled = useAppConfigStore((state) => state.p2pool_enabled);
const setP2poolEnabled = useAppConfigStore((state) => state.setP2poolEnabled);
const miningAllowed = useAppStateStore((s) => !s.isSettingUp);
const miningAllowed = useAppStateStore((s) => s.setupComplete);
const setDialogToShow = useUIStore((s) => s.setDialogToShow);
const isDisabled = !miningAllowed;

Expand Down
5 changes: 2 additions & 3 deletions src/containers/main/Dashboard/components/VisualMode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,13 @@ function VisualMode() {
const isWebglNotSupported = useUIStore((s) => s.isWebglNotSupported);
const { t } = useTranslation('settings', { useSuspense: false });

const canvasElement = document.getElementById('canvas');

const handleSwitch = useCallback(() => {
const canvasElement = document.getElementById('canvas');
if (canvasElement) {
canvasElement.style.display = visualMode ? 'none' : 'block';
}
setVisualMode(!visualMode);
}, [canvasElement, setVisualMode, visualMode]);
}, [setVisualMode, visualMode]);

return (
<SettingsGroupWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { useUIStore } from '@app/store/useUIStore';

function ModeSelect() {
const { t } = useTranslation('common', { useSuspense: false });
const isSettingUp = useAppStateStore((s) => s.isSettingUp);
const isSettingUp = useAppStateStore((s) => !s.setupComplete);
const mode = useAppConfigStore((s) => s.mode);
const isCPUMining = useMiningMetricsStore((s) => s.cpu.mining.is_mining);
const isGPUMining = useMiningMetricsStore((s) => s.gpu.mining.is_mining);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const LostConnectionAlert = () => {
// const isConnectedToTari = useMiningStore((s) => s.base_node?.is_connected);
// Hotfix for now
const isConnectedToTari = true;
const isSettingUp = useAppStateStore((s) => s.isSettingUp);
const isSettingUp = useAppStateStore((s) => !s.setupComplete);

return !isConnectedToTari && !isSettingUp ? (
<Stack direction="row" justifyContent="space-between" alignItems="center" style={{ padding: '0 6px' }} gap={6}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ enum MiningButtonStateText {

export default function MiningButton() {
const { t } = useTranslation('mining-view', { useSuspense: false });
const isAppSettingUp = useAppStateStore((s) => s.isSettingUp);
const isAppSettingUp = useAppStateStore((s) => !s.setupComplete);
const isMiningControlsEnabled = useMiningStore((s) => s.miningControlsEnabled);
const isMiningInitiated = useMiningStore((s) => s.miningInitiated);
const isCPUMining = useMiningMetricsStore((s) => s.cpu.mining.is_mining);
Expand Down
10 changes: 9 additions & 1 deletion src/glApp.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,19 @@ export type GlAppState =
| 'restartAnimation'
| 'restart';

interface PreloadArgs {
canvas?: HTMLElement | null;
orbitTarget?: HTMLElement | null;
ASSETS_PATH: string;
}
export interface GlApp {
setState(e: GlAppState, isReplay?: boolean): void;
init(): void;
init: () => void;
render: (dt: number) => void;
setSize: (w: number, h: number) => void;
properties: Properties;
stateManager: StateManager;
preload: ({ canvas, orbitTarget, ASSETS_PATH }: PreloadArgs, callback: () => void) => void;
}

export interface Properties extends Record<string, unknown> {
Expand Down
15 changes: 13 additions & 2 deletions src/hooks/app/isAppReady.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { once } from '@tauri-apps/api/event';
import { listen } from '@tauri-apps/api/event';
import { useEffect, useState } from 'react';
import { setSetupComplete } from '@app/store/appStateStore.ts';

interface Payload {
setup_complete?: boolean;
}
export const useIsAppReady = () => {
const [isAppReady, setIsAppReady] = useState(false);
useEffect(() => {
const listener = once('app_ready', () => {
const listener = listen('app_ready', ({ event: _, payload: p }) => {
if (p) {
const payload = p as Payload;

if (payload.setup_complete) {
setSetupComplete();
}
}
setIsAppReady(true);
});
return () => {
Expand Down
Loading

0 comments on commit 086a6fb

Please sign in to comment.