mirror of
https://github.com/everoddandeven/monerod-gui.git
synced 2025-01-03 09:29:36 +00:00
Automatic upgrade and disable sync on wifi implementation
This commit is contained in:
parent
10f771f890
commit
c95017f4d9
10 changed files with 336 additions and 96 deletions
|
@ -111,6 +111,7 @@ Maybe you only want to execute the application in the browser with hot reload? J
|
|||
| `npm run ng:serve` | Execute the app in the web browser (DEV mode) |
|
||||
| `npm run web:build` | Build the app that can be used directly in the web browser. Your built files are in the /dist folder. |
|
||||
| `npm run electron:local` | Builds your application and start electron locally |
|
||||
| `npm run electron:local:dev` | Builds your application and start electron locally (DEV MODE) |
|
||||
| `npm run electron:build` | Builds your application and creates an app consumable based on your operating system |
|
||||
|
||||
**Your application is optimised. Only /dist folder and NodeJS dependencies are included in the final bundle.**
|
||||
|
|
99
app/main.ts
99
app/main.ts
|
@ -1,5 +1,5 @@
|
|||
import { app, BrowserWindow, ipcMain, screen, dialog, Tray, Menu, MenuItemConstructorOptions } from 'electron';
|
||||
import { ChildProcessWithoutNullStreams, spawn } from 'child_process';
|
||||
import { ChildProcessWithoutNullStreams, exec, ExecException, spawn } from 'child_process';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
import * as https from 'https';
|
||||
|
@ -21,7 +21,13 @@ const args = process.argv.slice(1),
|
|||
function createWindow(): BrowserWindow {
|
||||
|
||||
const size = screen.getPrimaryDisplay().workAreaSize;
|
||||
const wdwIcon = path.join(__dirname, 'assets/icons/monero-symbol-on-white-480.png');
|
||||
let dirname = __dirname;
|
||||
|
||||
if (dirname.endsWith('/app')) {
|
||||
dirname = dirname.replace('/app', '/src')
|
||||
}
|
||||
|
||||
const wdwIcon = path.join(dirname, 'assets/icons/monero-symbol-on-white-480.png');
|
||||
|
||||
const trayMenuTemplate: MenuItemConstructorOptions[] = [
|
||||
{
|
||||
|
@ -128,14 +134,19 @@ function createWindow(): BrowserWindow {
|
|||
return win;
|
||||
}
|
||||
|
||||
function isWifiConnected() {
|
||||
function isWifiConnectedOld() {
|
||||
console.log("isWifiConnected()");
|
||||
const networkInterfaces = os.networkInterfaces();
|
||||
|
||||
console.log(`isWifiConnected(): network interfaces ${networkInterfaces}`);
|
||||
console.log(networkInterfaces);
|
||||
|
||||
for (const interfaceName in networkInterfaces) {
|
||||
const networkInterface = networkInterfaces[interfaceName];
|
||||
|
||||
if (networkInterface) {
|
||||
for (const network of networkInterface) {
|
||||
console.log(network);
|
||||
if (network.family === 'IPv4' && !network.internal && network.mac !== '00:00:00:00:00:00') {
|
||||
if (interfaceName.toLowerCase().includes('wifi') || interfaceName.toLowerCase().includes('wlan')) {
|
||||
return true;
|
||||
|
@ -147,6 +158,62 @@ function isWifiConnected() {
|
|||
return false;
|
||||
}
|
||||
|
||||
function isConnectedToWiFi(): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const platform = os.platform(); // Use os to get the platform
|
||||
|
||||
let command = '';
|
||||
if (platform === 'win32') {
|
||||
// Windows: Use 'netsh' command to check the Wi-Fi status
|
||||
command = 'netsh wlan show interfaces';
|
||||
} else if (platform === 'darwin') {
|
||||
// macOS: Use 'airport' command to check the Wi-Fi status
|
||||
command = "/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | grep 'state: running'";
|
||||
} else if (platform === 'linux') {
|
||||
// Linux: Use 'nmcli' to check for Wi-Fi connectivity
|
||||
command = 'nmcli dev status';
|
||||
} else {
|
||||
resolve(false); // Unsupported platform
|
||||
}
|
||||
|
||||
// Execute the platform-specific command
|
||||
if (command) {
|
||||
exec(command, (error: ExecException | null, stdout: string, stderr: string) => {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
reject(stderr);
|
||||
resolve(false); // In case of error, assume not connected to Wi-Fi
|
||||
} else {
|
||||
// Check if the output indicates a connected status
|
||||
if (stdout) {
|
||||
const components: string[] = stdout.split("\n");
|
||||
console.log(components);
|
||||
|
||||
components.forEach((component: string) => {
|
||||
if (component.includes('wifi') && !component.includes('--')) {
|
||||
resolve(true);
|
||||
}
|
||||
});
|
||||
|
||||
resolve(false);
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function isWifiConnected() {
|
||||
isConnectedToWiFi().then((connected: boolean) => {
|
||||
win?.webContents.send('is-wifi-connected-result', connected);
|
||||
}).catch((error: any) => {
|
||||
console.error(error);
|
||||
win?.webContents.send('is-wifi-connected-result', false);
|
||||
});
|
||||
}
|
||||
|
||||
function getMonerodVersion(monerodFilePath: string): void {
|
||||
const monerodProcess = spawn(monerodFilePath, [ '--version' ]);
|
||||
|
||||
|
@ -159,6 +226,8 @@ function getMonerodVersion(monerodFilePath: string): void {
|
|||
})
|
||||
}
|
||||
|
||||
let moneroFirstStdout: boolean = true;
|
||||
|
||||
function startMoneroDaemon(commandOptions: string[]): ChildProcessWithoutNullStreams {
|
||||
const monerodPath = commandOptions.shift();
|
||||
|
||||
|
@ -169,25 +238,40 @@ function startMoneroDaemon(commandOptions: string[]): ChildProcessWithoutNullStr
|
|||
|
||||
console.log("Starting monerod daemon with options: " + commandOptions.join(" "));
|
||||
|
||||
moneroFirstStdout = true;
|
||||
|
||||
// Avvia il processo usando spawn
|
||||
const monerodProcess = spawn(monerodPath, commandOptions);
|
||||
|
||||
// Gestisci l'output di stdout in streaming
|
||||
monerodProcess.stdout.on('data', (data) => {
|
||||
//console.log(`monerod stdout: ${data}`);
|
||||
const pattern = '**********************************************************************';
|
||||
|
||||
if (moneroFirstStdout && data.includes(pattern)) {
|
||||
win?.webContents.send('monerod-started', true);
|
||||
moneroFirstStdout = false;
|
||||
}
|
||||
|
||||
win?.webContents.send('monero-stdout', `${data}`);
|
||||
// Puoi anche inviare i log all'interfaccia utente tramite IPC
|
||||
});
|
||||
|
||||
// Gestisci gli errori in stderr
|
||||
monerodProcess.stderr.on('data', (data) => {
|
||||
//console.error(`monerod stderr: ${data}`);
|
||||
console.error(`monerod error: ${data}`);
|
||||
|
||||
if (moneroFirstStdout) {
|
||||
win?.webContents.send('monerod-started', false);
|
||||
moneroFirstStdout = false;
|
||||
}
|
||||
|
||||
win?.webContents.send('monero-stderr', `${data}`);
|
||||
});
|
||||
|
||||
// Gestisci la chiusura del processo
|
||||
monerodProcess.on('close', (code) => {
|
||||
console.log(`monerod chiuso con codice: ${code}`);
|
||||
monerodProcess.on('close', (code: number) => {
|
||||
console.log(`monerod exited with code: ${code}`);
|
||||
win?.webContents.send('monero-stdout', `monerod exited with code: ${code}`);
|
||||
win?.webContents.send('monero-close', code);
|
||||
});
|
||||
|
@ -421,7 +505,8 @@ try {
|
|||
});
|
||||
|
||||
ipcMain.handle('is-wifi-connected', async (event) => {
|
||||
win?.webContents.send('is-wifi-connected-result', isWifiConnected());
|
||||
isWifiConnected();
|
||||
//win?.webContents.send('is-wifi-connected-result', isWifiConnected());
|
||||
});
|
||||
|
||||
ipcMain.handle('get-os-type', (event) => {
|
||||
|
|
|
@ -6,6 +6,9 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
|||
startMonerod: (args) => {
|
||||
ipcRenderer.invoke('start-monerod', args);
|
||||
},
|
||||
onMonerodStarted: (callback) => {
|
||||
ipcRenderer.on('monerod-started', callback);
|
||||
},
|
||||
onMoneroStdout: (callback) => {
|
||||
ipcRenderer.on('monero-stdout', callback);
|
||||
},
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
"electron:serve-tsc": "tsc -p tsconfig.serve.json",
|
||||
"electron:serve": "wait-on tcp:4200 && npm run electron:serve-tsc && electron . --serve",
|
||||
"electron:local": "npm run build:prod && electron .",
|
||||
"electron:local:dev": "npm run build:dev && electron .",
|
||||
"electron:build": "npm run build:prod && electron-builder build --publish=never",
|
||||
"test": "ng test --watch=false",
|
||||
"test:watch": "ng test",
|
||||
|
|
|
@ -60,7 +60,7 @@ export class DaemonDataService {
|
|||
private _txPoolBacklog: TxBacklogEntry[] = [];
|
||||
private _gettingTxPoolBackLog: boolean = false;
|
||||
|
||||
public readonly syncStart: EventEmitter<void> = new EventEmitter<void>();
|
||||
public readonly syncStart: EventEmitter<{ first: boolean }> = new EventEmitter<{ first: boolean }>();
|
||||
public readonly syncEnd: EventEmitter<void> = new EventEmitter<void>();
|
||||
public readonly syncError: EventEmitter<Error> = new EventEmitter<Error>();
|
||||
|
||||
|
@ -91,7 +91,7 @@ export class DaemonDataService {
|
|||
}
|
||||
|
||||
public get running(): boolean {
|
||||
return this._daemonRunning;
|
||||
return this._daemonRunning
|
||||
}
|
||||
|
||||
public get starting(): boolean {
|
||||
|
@ -239,11 +239,17 @@ export class DaemonDataService {
|
|||
throw new Error("Loop already started");
|
||||
}
|
||||
this._firstRefresh = true;
|
||||
|
||||
this.refresh().then(() => {
|
||||
this.refreshInterval = setInterval(() => {
|
||||
this.refresh().then().catch((error: any) => {
|
||||
console.error(error);
|
||||
});
|
||||
},this.refreshTimeoutMs);
|
||||
}).catch((error: any) => {
|
||||
console.error(error);
|
||||
this._refreshing = false;
|
||||
});
|
||||
}
|
||||
|
||||
private stopLoop(): void {
|
||||
|
@ -320,7 +326,31 @@ export class DaemonDataService {
|
|||
}
|
||||
|
||||
this._refreshing = true;
|
||||
this.syncStart.emit();
|
||||
|
||||
const settings = await this.daemonService.getSettings();
|
||||
|
||||
const updateInfo = await this.daemonService.checkUpdate()
|
||||
|
||||
if (updateInfo.update) {
|
||||
await this.daemonService.upgrade();
|
||||
return;
|
||||
}
|
||||
|
||||
const syncAlreadyDisabled = this.daemonService.settings.noSync;
|
||||
const wifiConnected = await this.daemonService.isWifiConnected();
|
||||
|
||||
if (!settings.noSync && !syncAlreadyDisabled && !settings.syncOnWifi && wifiConnected) {
|
||||
console.log("Disabling sync ...");
|
||||
|
||||
await this.daemonService.disableSync();
|
||||
}
|
||||
else if (!settings.noSync && syncAlreadyDisabled && !settings.syncOnWifi && !wifiConnected) {
|
||||
console.log("Enabling sync ...");
|
||||
|
||||
await this.daemonService.enableSync();
|
||||
}
|
||||
|
||||
this.syncStart.emit({ first: this._firstRefresh });
|
||||
|
||||
try {
|
||||
const firstRefresh = this._firstRefresh;
|
||||
|
@ -337,6 +367,11 @@ export class DaemonDataService {
|
|||
this._daemonInfo = await this.daemonService.getInfo();
|
||||
this._gettingDaemonInfo = false;
|
||||
|
||||
if (this.daemonService.settings.upgradeAutomatically && this._daemonInfo.updateAvailable) {
|
||||
await this.daemonService.upgrade();
|
||||
return;
|
||||
}
|
||||
|
||||
this._gettingSyncInfo = true;
|
||||
this.syncInfoRefreshStart.emit();
|
||||
this._syncInfo = await this.daemonService.syncInfo();
|
||||
|
|
|
@ -79,6 +79,7 @@ import { DaemonSettings } from '../../../../common/DaemonSettings';
|
|||
import { MethodNotFoundError } from '../../../../common/error/MethodNotFoundError';
|
||||
import { openDB, IDBPDatabase } from "idb"
|
||||
import { PeerInfo, TxPool } from '../../../../common';
|
||||
import { MoneroInstallerService } from '../monero-installer/monero-installer.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
@ -100,6 +101,9 @@ export class DaemonService {
|
|||
public stopping: boolean = false;
|
||||
public starting: boolean = false;
|
||||
public restarting: boolean = false;
|
||||
public disablingSync: boolean = false;
|
||||
public enablingSync: boolean = false;
|
||||
|
||||
public readonly onDaemonStatusChanged: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||
public readonly onDaemonStopStart: EventEmitter<void> = new EventEmitter<void>();
|
||||
public readonly onDaemonStopEnd: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
@ -111,9 +115,10 @@ export class DaemonService {
|
|||
"Access-Control-Allow-Methods": 'POST,GET' // this states the allowed methods
|
||||
};
|
||||
|
||||
constructor(private httpClient: HttpClient, private electronService: ElectronService) {
|
||||
constructor(private installer: MoneroInstallerService, private httpClient: HttpClient, private electronService: ElectronService) {
|
||||
this.openDbPromise = this.openDatabase();
|
||||
this.settings = this.loadSettings();
|
||||
this.settings = new DaemonSettings();
|
||||
|
||||
const wdw = (window as any);
|
||||
|
||||
if (this.electronService.isElectron) {
|
||||
|
@ -132,6 +137,85 @@ export class DaemonService {
|
|||
}
|
||||
}
|
||||
|
||||
public async isWifiConnected(): Promise<boolean> {
|
||||
try {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
try {
|
||||
window.electronAPI.onIsWifiConnectedResponse((event: any, connected: boolean) => {
|
||||
console.debug(event);
|
||||
resolve(connected);
|
||||
});
|
||||
|
||||
window.electronAPI.isWifiConnected();
|
||||
}
|
||||
catch(error: any) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(error: any) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public async disableSync(): Promise<void> {
|
||||
this.disablingSync = true;
|
||||
|
||||
try {
|
||||
const running: boolean = await this.isRunning();
|
||||
|
||||
if (!running) {
|
||||
throw new Error("Daemon not running");
|
||||
}
|
||||
|
||||
if (this.settings.noSync) {
|
||||
throw new Error("Daemon already not syncing");
|
||||
}
|
||||
|
||||
await this.stopDaemon();
|
||||
|
||||
this.settings.noSync = true;
|
||||
|
||||
await this.startDaemon(this.settings);
|
||||
}
|
||||
catch(error: any) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
this.disablingSync = false;
|
||||
}
|
||||
|
||||
|
||||
public async enableSync(): Promise<void> {
|
||||
this.enablingSync = true;
|
||||
|
||||
try {
|
||||
const running: boolean = await this.isRunning();
|
||||
|
||||
if (!running) {
|
||||
throw new Error("Daemon not running");
|
||||
}
|
||||
|
||||
if (!this.settings.noSync) {
|
||||
throw new Error("Daemon already not syncing");
|
||||
}
|
||||
|
||||
await this.stopDaemon();
|
||||
|
||||
this.settings.noSync = false;
|
||||
|
||||
await this.startDaemon(this.settings);
|
||||
}
|
||||
catch(error: any) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
this.enablingSync = false;
|
||||
}
|
||||
|
||||
|
||||
private onClose(): void {
|
||||
this.daemonRunning = false;
|
||||
this.stopping = false;
|
||||
|
@ -156,7 +240,6 @@ export class DaemonService {
|
|||
public async saveSettings(settings: DaemonSettings, restartDaemon: boolean = true): Promise<void> {
|
||||
const db = await this.openDbPromise;
|
||||
await db.put(this.storeName, { id: 1, ...settings });
|
||||
this.settings = settings;
|
||||
|
||||
if (restartDaemon) {
|
||||
const running = await this.isRunning();
|
||||
|
@ -178,14 +261,12 @@ export class DaemonService {
|
|||
const db = await this.openDbPromise;
|
||||
const result = await db.get(this.storeName, 1);
|
||||
if (result) {
|
||||
this.settings = DaemonSettings.parse(result);
|
||||
return DaemonSettings.parse(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.settings = new DaemonSettings();
|
||||
return new DaemonSettings();
|
||||
}
|
||||
|
||||
return this.settings;
|
||||
}
|
||||
|
||||
public async deleteSettings(): Promise<void> {
|
||||
|
@ -193,32 +274,7 @@ export class DaemonService {
|
|||
await db.delete(this.storeName, 1);
|
||||
}
|
||||
|
||||
private loadSettings(): DaemonSettings {
|
||||
/*
|
||||
const args = [
|
||||
'--testnet',
|
||||
'--fast-block-sync', '1',
|
||||
'--prune-blockchain',
|
||||
'--sync-pruned-blocks',
|
||||
'--confirm-external-bind',
|
||||
'--max-concurrency', '1',
|
||||
'--log-level', '1',
|
||||
'--rpc-access-control-origins=*'
|
||||
];
|
||||
*/
|
||||
const settings = new DaemonSettings();
|
||||
settings.testnet = true;
|
||||
settings.fastBlockSync = true;
|
||||
settings.pruneBlockchain = true;
|
||||
settings.syncPrunedBlocks = true;
|
||||
settings.confirmExternalBind = true;
|
||||
settings.logLevel = 1;
|
||||
settings.rpcAccessControlOrigins = "*";
|
||||
return settings;
|
||||
}
|
||||
|
||||
private raiseRpcError(error: RpcError): void {
|
||||
|
||||
if (error.code == -9) {
|
||||
throw new CoreIsBusyError();
|
||||
}
|
||||
|
@ -229,7 +285,6 @@ export class DaemonService {
|
|||
{
|
||||
throw new Error(error.message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async delay(ms: number = 0): Promise<void> {
|
||||
|
@ -281,7 +336,8 @@ export class DaemonService {
|
|||
}
|
||||
}
|
||||
|
||||
public async startDaemon(): Promise<void> {
|
||||
public async startDaemon(customSettings?: DaemonSettings): Promise<void> {
|
||||
await new Promise<void>(async (resolve, reject) => {
|
||||
if (await this.isRunning()) {
|
||||
console.warn("Daemon already running");
|
||||
return;
|
||||
|
@ -290,27 +346,55 @@ export class DaemonService {
|
|||
this.starting = true;
|
||||
|
||||
console.log("Starting daemon");
|
||||
const settings = await this.getSettings();
|
||||
|
||||
if (this.electronService.ipcRenderer) this.electronService.ipcRenderer.send('start-monerod', settings.toCommandOptions());
|
||||
else {
|
||||
(window as any).electronAPI.startMonerod(settings.toCommandOptions());
|
||||
this.settings = customSettings ? customSettings : await this.getSettings();
|
||||
|
||||
if (!this.settings.noSync && !this.settings.syncOnWifi) {
|
||||
const wifiConnected = await this.isWifiConnected();
|
||||
|
||||
if (wifiConnected) {
|
||||
console.log("Disabling sync ...");
|
||||
|
||||
this.settings.noSync = true;
|
||||
}
|
||||
}
|
||||
else if (!this.settings.noSync && !this.settings.syncOnWifi) {
|
||||
const wifiConnected = await this.isWifiConnected();
|
||||
|
||||
if (!wifiConnected) {
|
||||
console.log("Enabling sync ...");
|
||||
|
||||
this.settings.noSync = false;
|
||||
}
|
||||
}
|
||||
|
||||
await this.delay(3000);
|
||||
window.electronAPI.onMonerodStarted((event: any, started: boolean) => {
|
||||
console.debug(event);
|
||||
|
||||
if (await this.isRunning(true)) {
|
||||
if (started) {
|
||||
console.log("Daemon started");
|
||||
this.onDaemonStatusChanged.emit(true);
|
||||
resolve();
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
console.log("Daemon not started");
|
||||
this.onDaemonStatusChanged.emit(false);
|
||||
reject('Could not start daemon');
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
window.electronAPI.startMonerod(this.settings.toCommandOptions());
|
||||
|
||||
});
|
||||
|
||||
this.starting = false;
|
||||
|
||||
const isRunning: boolean = await this.isRunning(true);
|
||||
|
||||
if (!isRunning) {
|
||||
throw new Error("Daemon started but not running");
|
||||
}
|
||||
}
|
||||
|
||||
public async restartDaemon(): Promise<void> {
|
||||
|
@ -965,6 +1049,25 @@ export class DaemonService {
|
|||
return response.height;
|
||||
}
|
||||
|
||||
public async upgrade(): Promise<void> {
|
||||
const settings = await this.getSettings();
|
||||
if (settings.upgradeAutomatically) {
|
||||
throw new Error('Monero Daemon will upgrade automatically');
|
||||
}
|
||||
if (settings.downloadUpgradePath == '') {
|
||||
throw new Error("Download path not configured");
|
||||
}
|
||||
|
||||
//const downloadUrl = 'https://downloads.getmonero.org/cli/linux64'; // Cambia in base al sistema
|
||||
const destination = settings.downloadUpgradePath; // Aggiorna con il percorso desiderato
|
||||
|
||||
const moneroFolder = await this.installer.downloadMonero(destination);
|
||||
|
||||
settings.monerodPath = `${moneroFolder}/monerod`;
|
||||
|
||||
await this.saveSettings(settings);
|
||||
}
|
||||
|
||||
public async update(command: 'check' | 'download', path: string = ''): Promise<UpdateInfo> {
|
||||
const response = await this.callRpc(new UpdateRequest(command, path));
|
||||
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import { Component, AfterViewInit, NgZone } from '@angular/core';
|
||||
import { Component, AfterViewInit, NgZone, OnDestroy } from '@angular/core';
|
||||
import { Peer } from '../../../common/Peer';
|
||||
import { NavbarLink } from '../../shared/components/navbar/navbar.model';
|
||||
import { NavbarService } from '../../shared/components/navbar/navbar.service';
|
||||
import { DaemonService, DaemonDataService } from '../../core/services';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-detail',
|
||||
templateUrl: './detail.component.html',
|
||||
styleUrls: ['./detail.component.scss']
|
||||
})
|
||||
export class DetailComponent implements AfterViewInit {
|
||||
export class DetailComponent implements AfterViewInit, OnDestroy {
|
||||
|
||||
public get daemonRunning(): boolean {
|
||||
return this.daemonData.running;
|
||||
|
@ -107,6 +108,8 @@ export class DetailComponent implements AfterViewInit {
|
|||
|
||||
public cards: Card[];
|
||||
|
||||
private subscriptions: Subscription[] = [];
|
||||
|
||||
constructor(
|
||||
private daemonService: DaemonService,
|
||||
private navbarService: NavbarService,
|
||||
|
@ -121,7 +124,18 @@ export class DetailComponent implements AfterViewInit {
|
|||
|
||||
this.cards = this.createCards();
|
||||
|
||||
this.daemonData.syncInfoRefreshEnd.subscribe(() => {
|
||||
this.subscriptions.push(this.daemonData.syncStart.subscribe((info) => {
|
||||
if(!info.first) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.ngZone.run(() => {
|
||||
this.cards = this.createLoadingCards();
|
||||
});
|
||||
|
||||
}));
|
||||
|
||||
this.subscriptions.push(this.daemonData.syncInfoRefreshEnd.subscribe(() => {
|
||||
const $table = $('#table');
|
||||
//$table.bootstrapTable({});
|
||||
$table.bootstrapTable('refreshOptions', {
|
||||
|
@ -135,10 +149,11 @@ export class DetailComponent implements AfterViewInit {
|
|||
}
|
||||
|
||||
this.cards = this.createCards();
|
||||
})
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
public ngAfterViewInit(): void {
|
||||
console.log('DetailComponent AFTER VIEW INIT');
|
||||
this.navbarService.setLinks(this.navbarLinks);
|
||||
this.ngZone.run(() => {
|
||||
|
@ -155,6 +170,11 @@ export class DetailComponent implements AfterViewInit {
|
|||
});
|
||||
}
|
||||
|
||||
public ngOnDestroy(): void {
|
||||
this.subscriptions.forEach((sub) => sub.unsubscribe());
|
||||
this.subscriptions = [];
|
||||
}
|
||||
|
||||
private createLoadingCards(): Card[] {
|
||||
return [
|
||||
new Card('Connection Status', this.connectionStatus, true),
|
||||
|
|
|
@ -4,6 +4,7 @@ import { DaemonService } from '../../core/services/daemon/daemon.service';
|
|||
import { SimpleBootstrapCard } from '../../shared/utils';
|
||||
import { DaemonVersion } from '../../../common/DaemonVersion';
|
||||
import { DaemonDataService, ElectronService, MoneroInstallerService } from '../../core/services';
|
||||
import { DaemonSettings } from '../../../common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-version',
|
||||
|
@ -15,6 +16,7 @@ export class VersionComponent implements AfterViewInit {
|
|||
public cards: SimpleBootstrapCard[];
|
||||
public currentVersion?: DaemonVersion;
|
||||
public latestVersion?: DaemonVersion;
|
||||
public settings: DaemonSettings = new DaemonSettings();
|
||||
|
||||
public get buttonDisabled(): boolean {
|
||||
const title = this.buttonTitle;
|
||||
|
@ -23,7 +25,7 @@ export class VersionComponent implements AfterViewInit {
|
|||
return false;
|
||||
}
|
||||
|
||||
const configured = this.daemonService.settings.monerodPath != '';
|
||||
const configured = this.settings.monerodPath != '';
|
||||
const updateAvailable = this.daemonData.info ? this.daemonData.info.updateAvailable : false;
|
||||
|
||||
if (title == 'Upgrade' && configured && updateAvailable) {
|
||||
|
@ -40,7 +42,7 @@ export class VersionComponent implements AfterViewInit {
|
|||
return 'Upgrade';
|
||||
}
|
||||
|
||||
const notConfigured = this.daemonService.settings.monerodPath == '';
|
||||
const notConfigured = this.settings.monerodPath == '';
|
||||
|
||||
if (notConfigured) {
|
||||
return 'Install';
|
||||
|
@ -87,6 +89,7 @@ export class VersionComponent implements AfterViewInit {
|
|||
}
|
||||
|
||||
public async load(): Promise<void> {
|
||||
this.settings = await this.daemonService.getSettings();
|
||||
const isElectron = this.electronService.isElectron || (window as any).electronAPI != null;
|
||||
const version = await this.daemonService.getVersion(isElectron);
|
||||
const latestVersion = await this.daemonService.getLatestVersion();
|
||||
|
@ -109,22 +112,7 @@ export class VersionComponent implements AfterViewInit {
|
|||
|
||||
this.upgrading = true;
|
||||
try {
|
||||
const settings = await this.daemonService.getSettings();
|
||||
if (settings.upgradeAutomatically) {
|
||||
throw new Error('Monero Daemon will upgrade automatically');
|
||||
}
|
||||
if (settings.downloadUpgradePath == '') {
|
||||
throw new Error("Download path not configured");
|
||||
}
|
||||
|
||||
//const downloadUrl = 'https://downloads.getmonero.org/cli/linux64'; // Cambia in base al sistema
|
||||
const destination = settings.downloadUpgradePath; // Aggiorna con il percorso desiderato
|
||||
|
||||
const moneroFolder = await this.moneroInstaller.downloadMonero(destination);
|
||||
|
||||
settings.monerodPath = `${moneroFolder}/monerod`;
|
||||
|
||||
await this.daemonService.saveSettings(settings);
|
||||
await this.daemonService.upgrade();
|
||||
|
||||
this.upgradeError = '';
|
||||
this.upgradeSuccess = true;
|
||||
|
|
|
@ -58,10 +58,14 @@ import 'bootstrap-table';
|
|||
declare global {
|
||||
interface Window {
|
||||
electronAPI: {
|
||||
startMonerod: (args: string[]) => void;
|
||||
startMonerod: (options: string[]) => void;
|
||||
onMonerodStarted: (callback: (event: any, started: boolean) => void) => void;
|
||||
isWifiConnected: () => void;
|
||||
onIsWifiConnectedResponse: (callback: (event: any, connected: boolean) => void) => void;
|
||||
getOsType: () => void;
|
||||
gotOsType: (callback: (event: any, osType: { platform: string, arch: string }) => void) => void;
|
||||
quit: () => void;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue