diff --git a/src/app/core/services/daemon/daemon-data.service.ts b/src/app/core/services/daemon/daemon-data.service.ts index 80171a7..1b0d1fe 100644 --- a/src/app/core/services/daemon/daemon-data.service.ts +++ b/src/app/core/services/daemon/daemon-data.service.ts @@ -15,7 +15,6 @@ export class DaemonDataService { private _lastRefreshHeight: number = -1; private _daemonRunning: boolean = false; - private _daemonRestarting: boolean = false; private _daemonInfo?: DaemonInfo; private _gettingDaemonInfo: boolean = false; @@ -97,7 +96,7 @@ export class DaemonDataService { } public get restarting(): boolean { - return this._daemonRestarting; + return this.daemonService.restarting; } public get refreshing(): boolean { diff --git a/src/app/core/services/daemon/daemon.service.ts b/src/app/core/services/daemon/daemon.service.ts index f55ad16..a4fd7d7 100644 --- a/src/app/core/services/daemon/daemon.service.ts +++ b/src/app/core/services/daemon/daemon.service.ts @@ -99,6 +99,7 @@ export class DaemonService { //private url: string = "https://moneronode.org:18081"; public stopping: boolean = false; public starting: boolean = false; + public restarting: boolean = false; public readonly onDaemonStatusChanged: EventEmitter = new EventEmitter(); public readonly onDaemonStopStart: EventEmitter = new EventEmitter(); public readonly onDaemonStopEnd: EventEmitter = new EventEmitter(); @@ -148,10 +149,25 @@ export class DaemonService { }); } - public async saveSettings(settings: DaemonSettings): Promise { + public async saveSettings(settings: DaemonSettings, restartDaemon: boolean = true): Promise { const db = await this.openDbPromise; await db.put(this.storeName, { id: 1, ...settings }); this.settings = settings; + + if (restartDaemon) { + const running = await this.isRunning(); + + if (!running) { + return; + } + + try { + await this.restartDaemon(); + } + catch(error) { + console.error(error); + } + } } public async getSettings(): Promise { @@ -293,6 +309,32 @@ export class DaemonService { } + public async restartDaemon(): Promise { + this.restarting = true; + let err: any = undefined; + try { + const running = await this.isRunning(); + + if (!running) { + await this.startDaemon(); + } + else { + await this.stopDaemon(); + await this.startDaemon(); + } + } + catch(error) { + console.error(error); + err = error; + } + + this.restarting = false; + + if (err) { + throw err; + } + } + private async checkDaemonIsRunning(): Promise { try { await this.callRpc(new EmptyRpcRequest()); @@ -757,6 +799,7 @@ export class DaemonService { console.warn("Daemon is starting"); return; } + this.stopping = true; this.onDaemonStopStart.emit(); @@ -771,6 +814,7 @@ export class DaemonService { for(let i = 0; i < maxChecks; i++) { if (!await this.isRunning(true)) { + this.stopping = false; return; } await this.delay(5000); diff --git a/src/app/pages/bans/bans.component.html b/src/app/pages/bans/bans.component.html index 4c6f764..e4f2b25 100644 --- a/src/app/pages/bans/bans.component.html +++ b/src/app/pages/bans/bans.component.html @@ -100,4 +100,3 @@ - \ No newline at end of file diff --git a/src/app/pages/blockchain/blockchain.component.html b/src/app/pages/blockchain/blockchain.component.html index dc2cf62..40a9d88 100644 --- a/src/app/pages/blockchain/blockchain.component.html +++ b/src/app/pages/blockchain/blockchain.component.html @@ -491,4 +491,3 @@ - \ No newline at end of file diff --git a/src/app/pages/detail/detail.component.html b/src/app/pages/detail/detail.component.html index 060f1e4..f482268 100644 --- a/src/app/pages/detail/detail.component.html +++ b/src/app/pages/detail/detail.component.html @@ -11,7 +11,7 @@ - +
diff --git a/src/app/pages/hard-fork-info/hard-fork-info.component.html b/src/app/pages/hard-fork-info/hard-fork-info.component.html index db36c89..1fc78a7 100644 --- a/src/app/pages/hard-fork-info/hard-fork-info.component.html +++ b/src/app/pages/hard-fork-info/hard-fork-info.component.html @@ -41,4 +41,3 @@
- \ No newline at end of file diff --git a/src/app/pages/mining/mining.component.html b/src/app/pages/mining/mining.component.html index 14664d7..35ea9ec 100644 --- a/src/app/pages/mining/mining.component.html +++ b/src/app/pages/mining/mining.component.html @@ -469,4 +469,3 @@
- \ No newline at end of file diff --git a/src/app/pages/network/network.component.html b/src/app/pages/network/network.component.html index 777685e..5763701 100644 --- a/src/app/pages/network/network.component.html +++ b/src/app/pages/network/network.component.html @@ -108,4 +108,3 @@ - \ No newline at end of file diff --git a/src/app/pages/outputs/outputs.component.html b/src/app/pages/outputs/outputs.component.html index 4ea169b..7699dc0 100644 --- a/src/app/pages/outputs/outputs.component.html +++ b/src/app/pages/outputs/outputs.component.html @@ -216,4 +216,3 @@ - \ No newline at end of file diff --git a/src/app/pages/peers/peers.component.html b/src/app/pages/peers/peers.component.html index a3f3609..12ca9b4 100644 --- a/src/app/pages/peers/peers.component.html +++ b/src/app/pages/peers/peers.component.html @@ -143,4 +143,3 @@ - \ No newline at end of file diff --git a/src/app/pages/settings/settings.component.html b/src/app/pages/settings/settings.component.html index edce798..e16c836 100644 --- a/src/app/pages/settings/settings.component.html +++ b/src/app/pages/settings/settings.component.html @@ -39,7 +39,7 @@
-
+

General

@@ -261,7 +261,7 @@
-
+

General

@@ -324,7 +324,7 @@
-
+

Bootstrap Daemon

@@ -403,6 +403,13 @@
Keep alternative blocks on restart
+ +
+ + +
+ Sync when node is connected to Wi-Fi +
@@ -419,7 +426,26 @@
- +
+ + +
+ Enable syncing in certain hours +
+ +
+ +
+ +
+
+ +
+ +
+ +
+

@@ -447,7 +473,7 @@
-
+
@@ -494,7 +520,7 @@
-
+
@@ -532,6 +558,9 @@
- - + +
diff --git a/src/app/pages/settings/settings.component.ts b/src/app/pages/settings/settings.component.ts index a2ef75c..899defb 100644 --- a/src/app/pages/settings/settings.component.ts +++ b/src/app/pages/settings/settings.component.ts @@ -1,6 +1,4 @@ import { AfterViewInit, Component } from '@angular/core'; -import { NavbarService } from '../../shared/components/navbar/navbar.service'; -import { Router } from '@angular/router'; import { NavbarLink } from '../../shared/components/navbar/navbar.model'; import { DaemonSettings } from '../../../common/DaemonSettings'; import { DaemonService } from '../../core/services/daemon/daemon.service'; @@ -13,25 +11,27 @@ import { DaemonService } from '../../core/services/daemon/daemon.service'; export class SettingsComponent implements AfterViewInit { public readonly navbarLinks: NavbarLink[]; + private originalSettings: DaemonSettings; public currentSettings: DaemonSettings; + public savingChanges: boolean = false; public rpcLoginUser: string; public rpcLoginPassword: string; public loading: boolean; public networkType: 'mainnet' | 'testnet' | 'stagenet' = 'mainnet'; - constructor(private router: Router, private navbarService: NavbarService, private daemonService: DaemonService) { + constructor(private daemonService: DaemonService) { this.loading = true; this.navbarLinks = [ - new NavbarLink('pills-general-tab', '#pills-general', 'pills-general', true, 'General'), - new NavbarLink('pills-rpc-tab', '#pills-rpc', 'pills-rpc', false, 'RPC'), - new NavbarLink('pills-p2p-tab', '#pills-p2p', 'pills-p2p', false, 'P2P'), - new NavbarLink('pills-blockchain-tab', '#pills-blockchain', 'pills-blockchain', false, 'Blockchain'), - new NavbarLink('pills-mining-tab', '#pills-mining', 'pills-mining', false, 'Mining'), - new NavbarLink('pills-logs-tab', '#pills-logs', 'pills-logs', false, 'Logs') + new NavbarLink('pills-general-tab', '#pills-general', 'pills-general', true, 'General', false), + new NavbarLink('pills-rpc-tab', '#pills-rpc', 'pills-rpc', false, 'RPC', false), + new NavbarLink('pills-p2p-tab', '#pills-p2p', 'pills-p2p', false, 'P2P', false), + new NavbarLink('pills-blockchain-tab', '#pills-blockchain', 'pills-blockchain', false, 'Blockchain', false), + new NavbarLink('pills-mining-tab', '#pills-mining', 'pills-mining', false, 'Mining', false), + new NavbarLink('pills-logs-tab', '#pills-logs', 'pills-logs', false, 'Logs', false) ]; this.originalSettings = new DaemonSettings(); @@ -66,9 +66,12 @@ export class SettingsComponent implements AfterViewInit { return false; } + public get saveDisabled(): boolean { + return !this.modified || this.daemonService.restarting || this.daemonService.starting || this.daemonService.stopping; + } + ngAfterViewInit(): void { - this.navbarService.setLinks(this.navbarLinks); - this.navbarService.enableLinks(); + } public OnOfflineChange() { @@ -143,9 +146,18 @@ export class SettingsComponent implements AfterViewInit { return; } - await this.daemonService.saveSettings(this.currentSettings); + this.savingChanges = true; - this.originalSettings = this.currentSettings.clone(); + try { + await this.daemonService.saveSettings(this.currentSettings); + + this.originalSettings = this.currentSettings.clone(); + } + catch(error) { + console.error(error); + } + + this.savingChanges = false; } public chooseMonerodFile(): void { diff --git a/src/app/pages/transactions/transactions.component.html b/src/app/pages/transactions/transactions.component.html index 90b8ccb..d90eafd 100644 --- a/src/app/pages/transactions/transactions.component.html +++ b/src/app/pages/transactions/transactions.component.html @@ -309,4 +309,3 @@ - \ No newline at end of file diff --git a/src/app/shared/components/daemon-not-running/daemon-not-running.component.html b/src/app/shared/components/daemon-not-running/daemon-not-running.component.html index 14eb173..9ca08a3 100644 --- a/src/app/shared/components/daemon-not-running/daemon-not-running.component.html +++ b/src/app/shared/components/daemon-not-running/daemon-not-running.component.html @@ -1,17 +1,32 @@ -
-

Daemon not running

-

Daemon not configured

-

Start monero daemon

-

Configure monero daemon

+
+

Daemon not running

+

Daemon not configured

+

Daemon restarting

+

Daemon is stopping

+ +

Start monero daemon

+

Configure monero daemon

Daemon is starting

Starting monero daemon

+

Restarting monero daemon

- + + + + + +   - +
\ No newline at end of file diff --git a/src/app/shared/components/daemon-not-running/daemon-not-running.component.ts b/src/app/shared/components/daemon-not-running/daemon-not-running.component.ts index d410ec3..6cdb646 100644 --- a/src/app/shared/components/daemon-not-running/daemon-not-running.component.ts +++ b/src/app/shared/components/daemon-not-running/daemon-not-running.component.ts @@ -10,17 +10,21 @@ import { DaemonDataService } from '../../../core/services'; export class DaemonNotRunningComponent { public get daemonRunning(): boolean { - return this.daemonData.running; + return this.daemonData.running && !this.startingDaemon && !this.stoppingDaemon && !this.restartingDaemon; } public daemonConfigured: boolean = true; public get startingDaemon(): boolean { - return this.daemonService.starting; + return this.daemonService.starting && !this.restartingDaemon; } - private get stoppingDaemon(): boolean{ - return this.daemonData.stopping; + public get stoppingDaemon(): boolean{ + return this.daemonData.stopping && !this.restartingDaemon; + } + + public get restartingDaemon(): boolean { + return this.daemonService.restarting; } constructor(private daemonData: DaemonDataService, private daemonService: DaemonService, private ngZone: NgZone) { @@ -50,6 +54,20 @@ export class DaemonNotRunningComponent { reject(error); } }, 500)}); - } + } + + public async restartDaemon(): Promise { + await new Promise((resolve, reject) => { + setTimeout(async () => { + try { + await this.daemonService.restartDaemon(); + resolve(); + } + catch(error) { + console.error(error); + reject(error); + } + }, 500)}); + } } diff --git a/src/app/shared/components/daemon-stopping/daemon-stopping.component.html b/src/app/shared/components/daemon-stopping/daemon-stopping.component.html deleted file mode 100644 index cb2aabc..0000000 --- a/src/app/shared/components/daemon-stopping/daemon-stopping.component.html +++ /dev/null @@ -1,8 +0,0 @@ -
-

Daemon is stopping

- - -
\ No newline at end of file diff --git a/src/app/shared/components/daemon-stopping/daemon-stopping.component.scss b/src/app/shared/components/daemon-stopping/daemon-stopping.component.scss deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/shared/components/daemon-stopping/daemon-stopping.component.spec.ts b/src/app/shared/components/daemon-stopping/daemon-stopping.component.spec.ts deleted file mode 100644 index b70bea1..0000000 --- a/src/app/shared/components/daemon-stopping/daemon-stopping.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { DaemonStoppingComponent } from './daemon-stopping.component'; - -describe('DaemonStoppingComponent', () => { - let component: DaemonStoppingComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [DaemonStoppingComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(DaemonStoppingComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/shared/components/daemon-stopping/daemon-stopping.component.ts b/src/app/shared/components/daemon-stopping/daemon-stopping.component.ts deleted file mode 100644 index 1880f0e..0000000 --- a/src/app/shared/components/daemon-stopping/daemon-stopping.component.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Component } from '@angular/core'; -import { DaemonService } from '../../../core/services/daemon/daemon.service'; - -@Component({ - selector: 'app-daemon-stopping', - templateUrl: './daemon-stopping.component.html', - styleUrl: './daemon-stopping.component.scss' -}) -export class DaemonStoppingComponent { - - public get stopping(): boolean { - return this.daemonService.stopping; - } - - constructor(private daemonService: DaemonService) { - - } - -} diff --git a/src/app/shared/components/index.ts b/src/app/shared/components/index.ts index 82389b5..216fee6 100644 --- a/src/app/shared/components/index.ts +++ b/src/app/shared/components/index.ts @@ -1,4 +1,3 @@ export * from './page-not-found/page-not-found.component'; export * from './sidebar/sidebar.component'; export * from './daemon-not-running/daemon-not-running.component'; -export * from './daemon-stopping/daemon-stopping.component'; diff --git a/src/app/shared/components/navbar/navbar.component.ts b/src/app/shared/components/navbar/navbar.component.ts index f2a3fbf..4684eec 100644 --- a/src/app/shared/components/navbar/navbar.component.ts +++ b/src/app/shared/components/navbar/navbar.component.ts @@ -28,6 +28,10 @@ export class NavbarComponent { return this.daemonService.stopping; } + public get restarting(): boolean { + return this.daemonService.restarting; + } + constructor(private navbarService: NavbarService, private daemonService: DaemonService, private ngZone: NgZone) { this.daemonService.isRunning().then((running: boolean) => { @@ -61,9 +65,7 @@ export class NavbarComponent { } public async restartDaemon(): Promise { - await this.stopDaemon(); - - await this.startDaemon(); + await this.daemonService.restartDaemon(); } public async quit(): Promise { diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index cdf1230..26fd663 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -3,15 +3,15 @@ import { CommonModule } from '@angular/common'; import { TranslateModule } from '@ngx-translate/core'; -import { PageNotFoundComponent, SidebarComponent, DaemonNotRunningComponent, DaemonStoppingComponent } from './components/'; +import { PageNotFoundComponent, SidebarComponent, DaemonNotRunningComponent } from './components/'; import { WebviewDirective } from './directives/'; import { FormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; import { NavbarComponent } from './components/navbar/navbar.component'; @NgModule({ - declarations: [PageNotFoundComponent, SidebarComponent, DaemonNotRunningComponent, DaemonStoppingComponent, NavbarComponent, WebviewDirective], + declarations: [PageNotFoundComponent, SidebarComponent, DaemonNotRunningComponent, NavbarComponent, WebviewDirective], imports: [CommonModule, TranslateModule, FormsModule, RouterModule], - exports: [TranslateModule, WebviewDirective, FormsModule, SidebarComponent, DaemonNotRunningComponent, DaemonStoppingComponent, NavbarComponent] + exports: [TranslateModule, WebviewDirective, FormsModule, SidebarComponent, DaemonNotRunningComponent, NavbarComponent] }) export class SharedModule {} diff --git a/src/common/DaemonSettings.ts b/src/common/DaemonSettings.ts index 75d04e7..eb25b6f 100644 --- a/src/common/DaemonSettings.ts +++ b/src/common/DaemonSettings.ts @@ -1,6 +1,11 @@ export class DaemonSettings { public monerodPath: string = ''; + public syncOnWifi: boolean = true; + public syncPeriodEnabled: boolean = false; + public syncPeriodFrom: any = '00:00'; + public syncPeriodTo: any = '00:00'; + public logFile: string = ''; public logLevel: number = 0; public maxLogFileSize: number = 104850000; @@ -131,7 +136,36 @@ export class DaemonSettings { public disableRpcBan: boolean = false; public equals(settings: DaemonSettings): boolean { - return this.toCommandOptions().join('') == settings.toCommandOptions().join(''); + //return this.toCommandOptions().join('') == settings.toCommandOptions().join(''); + return this.deepEqual(this, settings); + } + + private deepEqual(obj1: any, obj2: any): boolean { + // Se sono lo stesso riferimento, sono uguali + if (obj1 === obj2) return true; + + // Se uno dei due è nullo o non sono oggetti, non sono uguali + if (obj1 == null || obj2 == null || typeof obj1 !== 'object' || typeof obj2 !== 'object') { + return false; + } + + // Ottieni tutte le chiavi degli oggetti + const keys1 = Object.keys(obj1); + const keys2 = Object.keys(obj2); + + // Se hanno un numero diverso di chiavi, non sono uguali + if (keys1.length !== keys2.length) return false; + + // Controlla che ogni chiave e valore sia equivalente + for (let key of keys1) { + // Se una chiave di obj1 non esiste in obj2, non sono uguali + if (!keys2.includes(key)) return false; + + // Se il valore della proprietà non è uguale, effettua un confronto ricorsivo + if (!this.deepEqual(obj1[key], obj2[key])) return false; + } + + return true; } public clone(): DaemonSettings {