mirror of
https://github.com/everoddandeven/monerod-gui.git
synced 2024-12-22 11:39:25 +00:00
Disable run on battery feature
This commit is contained in:
parent
897cc00bb7
commit
9ac4cef1c0
14 changed files with 315 additions and 66 deletions
3
.github/workflows/macos.yml
vendored
3
.github/workflows/macos.yml
vendored
|
@ -53,6 +53,9 @@ jobs:
|
||||||
|
|
||||||
- name: Build the app
|
- name: Build the app
|
||||||
run: npm run electron:build
|
run: npm run electron:build
|
||||||
|
|
||||||
|
- name: List artifacts
|
||||||
|
run: ls release/
|
||||||
|
|
||||||
- name: Upload DMG artifact
|
- name: Upload DMG artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { app, BrowserWindow, ipcMain, screen, dialog, Tray, Menu, MenuItemConstructorOptions,
|
import { app, BrowserWindow, ipcMain, screen, dialog, Tray, Menu, MenuItemConstructorOptions,
|
||||||
IpcMainInvokeEvent, Notification, NotificationConstructorOptions, clipboard
|
IpcMainInvokeEvent, Notification, NotificationConstructorOptions, clipboard, powerMonitor
|
||||||
} from 'electron';
|
} from 'electron';
|
||||||
import { ChildProcessWithoutNullStreams, exec, ExecException, spawn } from 'child_process';
|
import { ChildProcessWithoutNullStreams, exec, ExecException, spawn } from 'child_process';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
@ -782,6 +782,13 @@ try {
|
||||||
})
|
})
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
|
ipcMain.handle('is-on-battery-power', (event: IpcMainInvokeEvent) => {
|
||||||
|
win?.webContents.send('on-is-on-battery-power', powerMonitor.isOnBatteryPower());
|
||||||
|
});
|
||||||
|
|
||||||
|
powerMonitor.on('on-ac', () => win?.webContents.send('on-ac'));
|
||||||
|
powerMonitor.on('on-battery', () => win?.webContents.send('on-battery'));
|
||||||
|
|
||||||
ipcMain.handle('is-auto-launched', (event: IpcMainInvokeEvent) => {
|
ipcMain.handle('is-auto-launched', (event: IpcMainInvokeEvent) => {
|
||||||
console.debug(event);
|
console.debug(event);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,21 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
||||||
onGetBatteryLevel: (callback) => {
|
onGetBatteryLevel: (callback) => {
|
||||||
ipcRenderer.on('on-get-battery-level', callback);
|
ipcRenderer.on('on-get-battery-level', callback);
|
||||||
},
|
},
|
||||||
|
isOnBatteryPower: () => {
|
||||||
|
ipcRenderer.invoke('is-on-battery-power');
|
||||||
|
},
|
||||||
|
onIsOnBatteryPower: (callback) => {
|
||||||
|
ipcRenderer.on('on-is-on-battery-power', callback);
|
||||||
|
},
|
||||||
|
unregisterOnIsOnBatteryPower: () => {
|
||||||
|
ipcRenderer.removeAllListeners('on-is-on-battery-power');
|
||||||
|
},
|
||||||
|
onAc: (callback) => {
|
||||||
|
ipcRenderer.on('on-ac', callback);
|
||||||
|
},
|
||||||
|
onBattery: (callback) => {
|
||||||
|
ipcRenderer.on('on-battery', callback);
|
||||||
|
},
|
||||||
unregisterOnGetBatteryLevel: () => {
|
unregisterOnGetBatteryLevel: () => {
|
||||||
ipcRenderer.removeAllListeners('on-get-battery-level');
|
ipcRenderer.removeAllListeners('on-get-battery-level');
|
||||||
},
|
},
|
||||||
|
|
|
@ -69,6 +69,11 @@ export class DaemonDataService {
|
||||||
private _txPoolStats?: TxPoolStats;
|
private _txPoolStats?: TxPoolStats;
|
||||||
private _gettingTxPoolStats: boolean = false;
|
private _gettingTxPoolStats: boolean = false;
|
||||||
|
|
||||||
|
private _runningOnBattery?: boolean;
|
||||||
|
public get runningOnBattery(): boolean {
|
||||||
|
return this._runningOnBattery === true;
|
||||||
|
}
|
||||||
|
|
||||||
public readonly syncStart: EventEmitter<{ first: boolean }> = new EventEmitter<{ first: boolean }>();
|
public readonly syncStart: EventEmitter<{ first: boolean }> = new EventEmitter<{ first: boolean }>();
|
||||||
public readonly syncEnd: EventEmitter<void> = new EventEmitter<void>();
|
public readonly syncEnd: EventEmitter<void> = new EventEmitter<void>();
|
||||||
public readonly syncError: EventEmitter<any> = new EventEmitter<any>();
|
public readonly syncError: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
@ -92,8 +97,12 @@ export class DaemonDataService {
|
||||||
this.stopLoop();
|
this.stopLoop();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.electronService.onAcPower.subscribe(() => this._runningOnBattery = false);
|
||||||
|
this.electronService.onBatteryPower.subscribe(() => this._runningOnBattery = true);
|
||||||
|
|
||||||
|
this.electronService.isOnBatteryPower().then((value: boolean) => this._runningOnBattery = value).catch((error: any) => console.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
public get initializing(): boolean {
|
public get initializing(): boolean {
|
||||||
|
@ -350,6 +359,8 @@ export class DaemonDataService {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public batteryLevel: number = 0;
|
||||||
|
|
||||||
public syncDisabledByWifiPolicy: boolean = false;
|
public syncDisabledByWifiPolicy: boolean = false;
|
||||||
public syncDisabledByPeriodPolicy: boolean = false;
|
public syncDisabledByPeriodPolicy: boolean = false;
|
||||||
|
|
||||||
|
@ -359,11 +370,30 @@ export class DaemonDataService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._runningOnBattery === undefined) {
|
||||||
|
this._runningOnBattery = await this.electronService.isOnBatteryPower();
|
||||||
|
}
|
||||||
|
|
||||||
this._refreshing = true;
|
this._refreshing = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const settings = await this.daemonService.getSettings();
|
const settings = await this.daemonService.getSettings();
|
||||||
|
|
||||||
|
if (this._runningOnBattery && !settings.runOnBattery) {
|
||||||
|
await this.daemonService.stopDaemon();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (this._runningOnBattery && settings.batteryLevelThreshold > 0) {
|
||||||
|
const batteryLevel = await this.electronService.getBatteryLevel();
|
||||||
|
|
||||||
|
if (batteryLevel <= settings.batteryLevelThreshold) {
|
||||||
|
await this.daemonService.stopDaemon();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.batteryLevel = batteryLevel;
|
||||||
|
}
|
||||||
|
|
||||||
const syncAlreadyDisabled = this.daemonService.settings.noSync;
|
const syncAlreadyDisabled = this.daemonService.settings.noSync;
|
||||||
|
|
||||||
if (!settings.noSync && !syncAlreadyDisabled && !settings.syncOnWifi) {
|
if (!settings.noSync && !syncAlreadyDisabled && !settings.syncOnWifi) {
|
||||||
|
@ -406,7 +436,6 @@ export class DaemonDataService {
|
||||||
else {
|
else {
|
||||||
this.syncDisabledByPeriodPolicy = false;
|
this.syncDisabledByPeriodPolicy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch(error: any) {
|
catch(error: any) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { EventEmitter, Injectable } from '@angular/core';
|
||||||
// If you import a module but never use any of the imported values other than as TypeScript types,
|
// If you import a module but never use any of the imported values other than as TypeScript types,
|
||||||
// the resulting javascript file will look as if you never imported the module at all.
|
// the resulting javascript file will look as if you never imported the module at all.
|
||||||
import * as childProcess from 'child_process';
|
import * as childProcess from 'child_process';
|
||||||
|
@ -17,6 +17,9 @@ export class ElectronService {
|
||||||
private _online: boolean = false;
|
private _online: boolean = false;
|
||||||
private _isProduction: boolean = false;
|
private _isProduction: boolean = false;
|
||||||
|
|
||||||
|
public readonly onAcPower: EventEmitter<void> = new EventEmitter<void>();
|
||||||
|
public readonly onBatteryPower: EventEmitter<void> = new EventEmitter<void>();
|
||||||
|
|
||||||
public get isProduction(): boolean {
|
public get isProduction(): boolean {
|
||||||
return this._isProduction;
|
return this._isProduction;
|
||||||
}
|
}
|
||||||
|
@ -26,6 +29,9 @@ export class ElectronService {
|
||||||
window.addEventListener('online', () => this._online = true);
|
window.addEventListener('online', () => this._online = true);
|
||||||
window.addEventListener('offline', () => this._online = false);
|
window.addEventListener('offline', () => this._online = false);
|
||||||
this._isProduction = APP_CONFIG.production;
|
this._isProduction = APP_CONFIG.production;
|
||||||
|
|
||||||
|
window.electronAPI.onBattery((event: any) => this.onBatteryPower.emit());
|
||||||
|
window.electronAPI.onAc((event: any) => this.onAcPower.emit());
|
||||||
}
|
}
|
||||||
|
|
||||||
public get online(): boolean {
|
public get online(): boolean {
|
||||||
|
@ -62,6 +68,19 @@ export class ElectronService {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async isOnBatteryPower(): Promise<boolean> {
|
||||||
|
const promise = new Promise<boolean>((resolve) => {
|
||||||
|
window.electronAPI.onIsOnBatteryPower((event: any, onBattery: boolean) => {
|
||||||
|
window.electronAPI.unregisterOnIsOnBatteryPower();
|
||||||
|
resolve(onBattery);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
window.electronAPI.isOnBatteryPower();
|
||||||
|
|
||||||
|
return await promise;
|
||||||
|
}
|
||||||
|
|
||||||
public async getBatteryLevel(): Promise<number> {
|
public async getBatteryLevel(): Promise<number> {
|
||||||
const promise = new Promise<number>((resolve) => {
|
const promise = new Promise<number>((resolve) => {
|
||||||
window.electronAPI.onGetBatteryLevel((event: any, level: number) => {
|
window.electronAPI.onGetBatteryLevel((event: any, level: number) => {
|
||||||
|
@ -72,7 +91,7 @@ export class ElectronService {
|
||||||
|
|
||||||
window.electronAPI.getBatteryLevel();
|
window.electronAPI.getBatteryLevel();
|
||||||
|
|
||||||
return await promise;
|
return (await promise)*100;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async isAutoLaunched(): Promise<boolean> {
|
public async isAutoLaunched(): Promise<boolean> {
|
||||||
|
|
|
@ -186,6 +186,26 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<hr class="my-4">
|
||||||
|
<h4 class="mb-3">Battery</h4>
|
||||||
|
|
||||||
|
<div class="row g-3">
|
||||||
|
|
||||||
|
<div class="form-check form-switch col-md-6">
|
||||||
|
<label for="run-on-battery" class="form-check-label">Run on battery</label>
|
||||||
|
<input class="form-control form-check-input" type="checkbox" role="switch" id="run-on-battery" [checked]="currentSettings.runOnBattery" [(ngModel)]="currentSettings.runOnBattery" [ngModelOptions]="{standalone: true}">
|
||||||
|
<br>
|
||||||
|
<small class="text-body-secondary">Enable monerod to run on battery power</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label for="battery-threshold" class="form-label">Battery level threshold</label>
|
||||||
|
<input [disabled]="!currentSettings.runOnBattery" type="number" min="0" max="100" class="form-control" id="battery-threshold" placeholder="0" [(ngModel)]="currentSettings.batteryLevelThreshold" [ngModelOptions]="{standalone: true}">
|
||||||
|
<small class="text-body-secondary">Stop monerod when battery threshold is reached (0 to disable)</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<hr class="my-4">
|
<hr class="my-4">
|
||||||
<h4 class="mb-3">Updates</h4>
|
<h4 class="mb-3">Updates</h4>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div *ngIf="!daemonRunning || stoppingDaemon || restartingDaemon || enablingSync || disablingSync || installing" class="h-100 p-5 text-bg-dark rounded-3 m-4 text-center">
|
<div *ngIf="!daemonRunning || stoppingDaemon || restartingDaemon || enablingSync || disablingSync || installing" class="h-100 p-5 text-bg-dark rounded-3 m-4 text-center">
|
||||||
<h2 *ngIf="!installing && !enablingSync && !disablingSync && !daemonRunning && !startingDaemon && !stoppingDaemon && !restartingDaemon && !upgrading && daemonConfigured && !quittingDaemon"><i class="bi bi-exclamation-diamond m-4"></i> Daemon not running</h2>
|
<h2 *ngIf="!installing && !enablingSync && !disablingSync && !daemonRunning && !startingDaemon && !stoppingDaemon && !restartingDaemon && !upgrading && daemonConfigured && !quittingDaemon"><i class="bi bi-exclamation-diamond m-4"></i> {{ cannotRunBecauseBatteryPolicy ? batteryTooLow ? 'Battery power is too low' : 'Cannot run on battery power' : 'Daemon not running' }}</h2>
|
||||||
<h2 *ngIf="!installing && !enablingSync && !disablingSync && !daemonRunning && !startingDaemon && !stoppingDaemon && !restartingDaemon && !upgrading && !daemonConfigured && !quittingDaemon"><i class="bi bi-exclamation-diamond m-4"></i> Daemon not configured or installed</h2>
|
<h2 *ngIf="!installing && !enablingSync && !disablingSync && !daemonRunning && !startingDaemon && !stoppingDaemon && !restartingDaemon && !upgrading && !daemonConfigured && !quittingDaemon"><i class="bi bi-exclamation-diamond m-4"></i> Daemon not configured or installed</h2>
|
||||||
<h2 *ngIf="!installing && !enablingSync && !disablingSync && restartingDaemon && !upgrading"><i class="bi bi-arrow-clockwise m-4"></i> Daemon restarting</h2>
|
<h2 *ngIf="!installing && !enablingSync && !disablingSync && restartingDaemon && !upgrading"><i class="bi bi-arrow-clockwise m-4"></i> Daemon restarting</h2>
|
||||||
<h2 *ngIf="!installing && !enablingSync && !disablingSync && stoppingDaemon && !upgrading && !quittingDaemon"><i class="bi bi-stop-fill m-4"></i> Daemon is stopping</h2>
|
<h2 *ngIf="!installing && !enablingSync && !disablingSync && stoppingDaemon && !upgrading && !quittingDaemon"><i class="bi bi-stop-fill m-4"></i> Daemon is stopping</h2>
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
<h2 *ngIf="!installing && enablingSync"><i class="bi bi-repeat m-4"></i>Daemon is enabling sync</h2>
|
<h2 *ngIf="!installing && enablingSync"><i class="bi bi-repeat m-4"></i>Daemon is enabling sync</h2>
|
||||||
<h2 *ngIf="!installing && disablingSync"><i class="bi bi-slash-circle m-4"></i>Daemon is disabling sync</h2>
|
<h2 *ngIf="!installing && disablingSync"><i class="bi bi-slash-circle m-4"></i>Daemon is disabling sync</h2>
|
||||||
|
|
||||||
<p *ngIf="!installing && !enablingSync && !disablingSync && !daemonRunning && !startingDaemon && !stoppingDaemon && !restartingDaemon && daemonConfigured && !upgrading && !quittingDaemon">Start monero daemon</p>
|
<p *ngIf="!installing && !enablingSync && !disablingSync && !daemonRunning && !startingDaemon && !stoppingDaemon && !restartingDaemon && daemonConfigured && !upgrading && !quittingDaemon"> {{ cannotRunBecauseBatteryPolicy ? 'Configure monero daemon' : 'Start monero daemon' }} </p>
|
||||||
<p *ngIf="!installing && !enablingSync && !disablingSync && !startingDaemon && !startingDaemon && !stoppingDaemon && !restartingDaemon && !daemonConfigured && !upgrading && !quittingDaemon">Configure or install monero daemon</p>
|
<p *ngIf="!installing && !enablingSync && !disablingSync && !startingDaemon && !startingDaemon && !stoppingDaemon && !restartingDaemon && !daemonConfigured && !upgrading && !quittingDaemon">Configure or install monero daemon</p>
|
||||||
|
|
||||||
<h2 *ngIf="!installing && !enablingSync && !disablingSync && startingDaemon"><i class="bi bi-play-fill m-4"></i> Daemon is starting</h2>
|
<h2 *ngIf="!installing && !enablingSync && !disablingSync && startingDaemon"><i class="bi bi-play-fill m-4"></i> Daemon is starting</h2>
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
<p *ngIf="!installing && enablingSync">Enabling monero daemon blockchain sync</p>
|
<p *ngIf="!installing && enablingSync">Enabling monero daemon blockchain sync</p>
|
||||||
<p *ngIf="!installing && disablingSync">Disabling monero daemon blokchain sync</p>
|
<p *ngIf="!installing && disablingSync">Disabling monero daemon blokchain sync</p>
|
||||||
|
|
||||||
<button *ngIf="!installing && !enablingSync && !disablingSync && !startingDaemon && !stoppingDaemon && !restartingDaemon && !upgrading && daemonConfigured && !quittingDaemon" class="btn btn-outline-light" type="button" (click)="startDaemon()"><i class="bi bi-play-fill"></i> Start</button>
|
<button *ngIf="!cannotRunBecauseBatteryPolicy && !installing && !enablingSync && !disablingSync && !startingDaemon && !stoppingDaemon && !restartingDaemon && !upgrading && daemonConfigured && !quittingDaemon" class="btn btn-outline-light" type="button" (click)="startDaemon()"><i class="bi bi-play-fill"></i> Start</button>
|
||||||
<button *ngIf="!installing && !enablingSync && !disablingSync && startingDaemon" class="btn btn-outline-light" type="button" disabled>
|
<button *ngIf="!installing && !enablingSync && !disablingSync && startingDaemon" class="btn btn-outline-light" type="button" disabled>
|
||||||
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
||||||
Starting monerod
|
Starting monerod
|
||||||
|
@ -53,7 +53,6 @@
|
||||||
Enabling sync
|
Enabling sync
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
||||||
<button *ngIf="!installing && disablingSync" class="btn btn-outline-light" type="button" disabled>
|
<button *ngIf="!installing && disablingSync" class="btn btn-outline-light" type="button" disabled>
|
||||||
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
||||||
Disabling sync
|
Disabling sync
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { Component, OnDestroy } from '@angular/core';
|
||||||
import { DaemonService } from '../../../core/services/daemon/daemon.service';
|
import { DaemonService } from '../../../core/services/daemon/daemon.service';
|
||||||
import { DaemonDataService, MoneroInstallerService } from '../../../core/services';
|
import { DaemonDataService, MoneroInstallerService } from '../../../core/services';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
|
import { DaemonSettings } from '../../../../common';
|
||||||
|
import { DaemonStatusService } from './daemon-status.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-daemon-not-running',
|
selector: 'app-daemon-not-running',
|
||||||
|
@ -11,70 +13,59 @@ import { Subscription } from 'rxjs';
|
||||||
export class DaemonNotRunningComponent implements OnDestroy {
|
export class DaemonNotRunningComponent implements OnDestroy {
|
||||||
|
|
||||||
public get upgrading(): boolean {
|
public get upgrading(): boolean {
|
||||||
return this.installer.upgrading && !this.quittingDaemon;
|
return this.statusService.upgrading;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get installing(): boolean {
|
public get installing(): boolean {
|
||||||
return this.installer.installing;
|
return this.statusService.installing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get daemonRunning(): boolean {
|
public get daemonRunning(): boolean {
|
||||||
return this.daemonData.running && !this.startingDaemon && !this.stoppingDaemon && !this.restartingDaemon && !this.upgrading && !this.quittingDaemon;
|
return this.statusService.daemonRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
public daemonConfigured: boolean = true;
|
public daemonConfigured: boolean = true;
|
||||||
|
|
||||||
public get disablingSync(): boolean {
|
public get disablingSync(): boolean {
|
||||||
return this.daemonService.disablingSync;
|
return this.statusService.disablingSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get enablingSync(): boolean {
|
public get enablingSync(): boolean {
|
||||||
return this.daemonService.enablingSync;
|
return this.statusService.enablingSync;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get startingDaemon(): boolean {
|
public get startingDaemon(): boolean {
|
||||||
return this.daemonService.starting && !this.restartingDaemon && !this.stoppingDaemon && !this.upgrading && !this.quittingDaemon;
|
return this.statusService.startingDaemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get stoppingDaemon(): boolean{
|
public get stoppingDaemon(): boolean{
|
||||||
return this.daemonData.stopping && !this.restartingDaemon && !this.startingDaemon && !this.upgrading && !this.quittingDaemon;
|
return this.statusService.stoppingDaemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get restartingDaemon(): boolean {
|
public get restartingDaemon(): boolean {
|
||||||
return this.daemonService.restarting && ! this.upgrading && !this.quittingDaemon;
|
return this.statusService.restartingDaemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get cannotRunBecauseBatteryPolicy(): boolean {
|
||||||
|
return this.statusService.cannotRunBecauseBatteryPolicy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get progressStatus(): string {
|
public get progressStatus(): string {
|
||||||
const progress = this.installer.progress;
|
return this.statusService.progressStatus;
|
||||||
|
|
||||||
if (progress.status == 'Downloading') {
|
|
||||||
return `${progress.status} ${progress.progress.toFixed(2)} %`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return progress.status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public get quittingDaemon(): boolean {
|
public get quittingDaemon(): boolean {
|
||||||
return this.daemonService.quitting;
|
return this.statusService.quittingDaemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get batteryTooLow(): boolean {
|
||||||
|
return this.statusService.batteryTooLow;
|
||||||
}
|
}
|
||||||
|
|
||||||
private subscriptions: Subscription[] = [];
|
private subscriptions: Subscription[] = [];
|
||||||
|
|
||||||
constructor(private installer: MoneroInstallerService, private daemonData: DaemonDataService, private daemonService: DaemonService) {
|
constructor(private statusService: DaemonStatusService) {
|
||||||
const onSavedSettingsSub: Subscription = this.daemonService.onSavedSettings.subscribe((settings) => {
|
|
||||||
this.daemonConfigured = settings.monerodPath != '';
|
|
||||||
});
|
|
||||||
|
|
||||||
this.daemonService.getSettings().then((settings) => {
|
|
||||||
this.daemonConfigured = settings.monerodPath != '';
|
|
||||||
}).catch((error: any) => {
|
|
||||||
console.error(error);
|
|
||||||
this.daemonConfigured = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.daemonService.isRunning().then().catch((error: any) => console.error(error));
|
|
||||||
|
|
||||||
this.subscriptions.push(onSavedSettingsSub);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnDestroy(): void {
|
public ngOnDestroy(): void {
|
||||||
|
@ -83,34 +74,11 @@ export class DaemonNotRunningComponent implements OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async startDaemon(): Promise<void> {
|
public async startDaemon(): Promise<void> {
|
||||||
if (this.daemonRunning) {
|
await this.statusService.startDaemon();
|
||||||
console.warn("Daemon already running");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.startingDaemon || this.stoppingDaemon) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await new Promise<void>((resolve, reject) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.daemonService.startDaemon().then(() => {
|
|
||||||
resolve();
|
|
||||||
}).catch((error: any) => {
|
|
||||||
reject(new Error(`${error}`));
|
|
||||||
});
|
|
||||||
}, 500)});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async restartDaemon(): Promise<void> {
|
public async restartDaemon(): Promise<void> {
|
||||||
await new Promise<void>((resolve, reject) => {
|
await this.statusService.restartDaemon();
|
||||||
setTimeout(() => {
|
|
||||||
this.daemonService.restartDaemon().then(() => {
|
|
||||||
resolve();
|
|
||||||
}).catch((error: any) => {
|
|
||||||
reject(new Error(`${error}`));
|
|
||||||
});
|
|
||||||
}, 500)});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { DaemonStatusService } from './daemon-status.service';
|
||||||
|
|
||||||
|
describe('DaemonStatusService', () => {
|
||||||
|
let service: DaemonStatusService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
service = TestBed.inject(DaemonStatusService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,159 @@
|
||||||
|
import { Injectable, NgZone } from '@angular/core';
|
||||||
|
import { DaemonDataService, DaemonService, ElectronService, MoneroInstallerService } from '../../../core/services';
|
||||||
|
import { Subscription } from 'rxjs';
|
||||||
|
import { DaemonSettings } from '../../../../common';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class DaemonStatusService {
|
||||||
|
|
||||||
|
public get upgrading(): boolean {
|
||||||
|
return this.installer.upgrading && !this.quittingDaemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get installing(): boolean {
|
||||||
|
return this.installer.installing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get daemonRunning(): boolean {
|
||||||
|
return this.daemonData.running && !this.startingDaemon && !this.stoppingDaemon && !this.restartingDaemon && !this.upgrading && !this.quittingDaemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get daemonConfigured(): boolean {
|
||||||
|
return this.settings ? this.settings.monerodPath != '' : true;
|
||||||
|
};
|
||||||
|
|
||||||
|
public get disablingSync(): boolean {
|
||||||
|
return this.daemonService.disablingSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get enablingSync(): boolean {
|
||||||
|
return this.daemonService.enablingSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get startingDaemon(): boolean {
|
||||||
|
return this.daemonService.starting && !this.restartingDaemon && !this.stoppingDaemon && !this.upgrading && !this.quittingDaemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get stoppingDaemon(): boolean{
|
||||||
|
return this.daemonData.stopping && !this.restartingDaemon && !this.startingDaemon && !this.upgrading && !this.quittingDaemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get restartingDaemon(): boolean {
|
||||||
|
return this.daemonService.restarting && ! this.upgrading && !this.quittingDaemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get cannotRunBecauseBatteryPolicy(): boolean {
|
||||||
|
return this.settings ? (this._runningOnBattery && !this.settings.runOnBattery) || (this.settings.runOnBattery && this.settings.batteryLevelThreshold > 0 && this._batteryLevel <= this.settings.batteryLevelThreshold) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get progressStatus(): string {
|
||||||
|
const progress = this.installer.progress;
|
||||||
|
|
||||||
|
if (progress.status == 'Downloading') {
|
||||||
|
return `${progress.status} ${progress.progress.toFixed(2)} %`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return progress.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get quittingDaemon(): boolean {
|
||||||
|
return this.daemonService.quitting;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get batteryTooLow(): boolean {
|
||||||
|
return this._batteryTooLow;
|
||||||
|
}
|
||||||
|
|
||||||
|
private subscriptions: Subscription[] = [];
|
||||||
|
private settings?: DaemonSettings;
|
||||||
|
|
||||||
|
private _runningOnBattery: boolean = false;
|
||||||
|
private _batteryTooLow: boolean = false;
|
||||||
|
private _batteryLevel: number = 0;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private installer: MoneroInstallerService, private daemonData: DaemonDataService,
|
||||||
|
private daemonService: DaemonService, private electronService: ElectronService,
|
||||||
|
private ngZone: NgZone
|
||||||
|
) {
|
||||||
|
const onSavedSettingsSub: Subscription = this.daemonService.onSavedSettings.subscribe((settings) => {
|
||||||
|
this.refresh().then().catch((error: any) => console.error(error));
|
||||||
|
});
|
||||||
|
|
||||||
|
const onDaemonStatusSub: Subscription = this.daemonService.onDaemonStatusChanged.subscribe((running: boolean) => {
|
||||||
|
this.refresh().then().catch((error: any) => console.error(error));
|
||||||
|
});
|
||||||
|
|
||||||
|
const onAcPower: Subscription = this.electronService.onAcPower.subscribe(() => {
|
||||||
|
this.refresh().then().catch((error: any) => console.error(error));
|
||||||
|
});
|
||||||
|
|
||||||
|
const onBatteryPower: Subscription = this.electronService.onBatteryPower.subscribe(() => {
|
||||||
|
this.refresh().then().catch((error: any) => console.error(error));
|
||||||
|
});
|
||||||
|
|
||||||
|
this.refresh().then().catch((error: any) => console.error(error));
|
||||||
|
|
||||||
|
this.subscriptions.push(onSavedSettingsSub, onDaemonStatusSub, onAcPower, onBatteryPower);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async refresh(): Promise<void> {
|
||||||
|
//await this.daemonService.isRunning();
|
||||||
|
this.ngZone.run(() => {
|
||||||
|
setTimeout(async () => {
|
||||||
|
this.settings = await this.daemonService.getSettings();
|
||||||
|
this._runningOnBattery = await this.electronService.isOnBatteryPower();
|
||||||
|
|
||||||
|
if (this._runningOnBattery) this._batteryLevel = await this.electronService.getBatteryLevel();
|
||||||
|
|
||||||
|
if (this.settings.runOnBattery && this._runningOnBattery && this.settings.batteryLevelThreshold > 0) {
|
||||||
|
const batteryLevel = await this.electronService.getBatteryLevel();
|
||||||
|
this._batteryTooLow = batteryLevel <= this.settings.batteryLevelThreshold;
|
||||||
|
console.log(`battery level: ${batteryLevel}, threshold: ${this.settings.batteryLevelThreshold}, too low: ${this._batteryTooLow}`);
|
||||||
|
}
|
||||||
|
else if (!this.settings.runOnBattery) {
|
||||||
|
this._batteryTooLow = false;
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dispose(): void {
|
||||||
|
this.subscriptions.forEach((sub: Subscription) => sub.unsubscribe());
|
||||||
|
this.subscriptions = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public async startDaemon(): Promise<void> {
|
||||||
|
if (this.daemonRunning) {
|
||||||
|
console.warn("Daemon already running");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.startingDaemon || this.stoppingDaemon) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await new Promise<void>((resolve, reject) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.daemonService.startDaemon().then(() => {
|
||||||
|
resolve();
|
||||||
|
}).catch((error: any) => {
|
||||||
|
reject(new Error(`${error}`));
|
||||||
|
});
|
||||||
|
}, 500)});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async restartDaemon(): Promise<void> {
|
||||||
|
await new Promise<void>((resolve, reject) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.daemonService.restartDaemon().then(() => {
|
||||||
|
resolve();
|
||||||
|
}).catch((error: any) => {
|
||||||
|
reject(new Error(`${error}`));
|
||||||
|
});
|
||||||
|
}, 500)});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -44,7 +44,7 @@
|
||||||
|
|
||||||
<ul class="navbar-nav flex-row">
|
<ul class="navbar-nav flex-row">
|
||||||
<li *ngIf="!quitting && !running && !stopping && !restarting && !installing && !upgrading && daemonConfigured" class="nav-item text-nowrap">
|
<li *ngIf="!quitting && !running && !stopping && !restarting && !installing && !upgrading && daemonConfigured" class="nav-item text-nowrap">
|
||||||
<button [disabled]="starting || enablingSync || disablingSync" class="btn btn-outline-secondary px-3 text-white" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Start Daemon" aria-expanded="false" aria-label="Start daemon" (click)="startDaemon()">
|
<button [disabled]="starting || enablingSync || disablingSync || cannotStart" class="btn btn-outline-secondary px-3 text-white" type="button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Start Daemon" aria-expanded="false" aria-label="Start daemon" (click)="startDaemon()">
|
||||||
<i class="bi bi-play-fill"></i>
|
<i class="bi bi-play-fill"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { DaemonDataService, MoneroInstallerService } from '../../../core/service
|
||||||
import { DaemonSettings } from '../../../../common';
|
import { DaemonSettings } from '../../../../common';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { Tooltip } from 'bootstrap';
|
import { Tooltip } from 'bootstrap';
|
||||||
|
import { DaemonStatusService } from '../daemon-not-running/daemon-status.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-navbar',
|
selector: 'app-navbar',
|
||||||
|
@ -70,7 +71,11 @@ export class NavbarComponent implements AfterViewInit, OnDestroy {
|
||||||
private daemonSettings: DaemonSettings = new DaemonSettings();
|
private daemonSettings: DaemonSettings = new DaemonSettings();
|
||||||
private subscriptions: Subscription[] = [];
|
private subscriptions: Subscription[] = [];
|
||||||
|
|
||||||
constructor(private navbarService: NavbarService, private daemonService: DaemonService, private daemonData: DaemonDataService, private installerService: MoneroInstallerService, private ngZone: NgZone) {
|
public get cannotStart(): boolean {
|
||||||
|
return this.statusService.cannotRunBecauseBatteryPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(private navbarService: NavbarService, private daemonService: DaemonService, private daemonData: DaemonDataService, private installerService: MoneroInstallerService, private statusService: DaemonStatusService, private ngZone: NgZone) {
|
||||||
const onSavedSettingsSub: Subscription = this.daemonService.onSavedSettings.subscribe((settings: DaemonSettings) => {
|
const onSavedSettingsSub: Subscription = this.daemonService.onSavedSettings.subscribe((settings: DaemonSettings) => {
|
||||||
this.daemonSettings = settings;
|
this.daemonSettings = settings;
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,6 +9,9 @@ export class DaemonSettings {
|
||||||
public syncPeriodFrom: string = '00:00';
|
public syncPeriodFrom: string = '00:00';
|
||||||
public syncPeriodTo: string = '00:00';
|
public syncPeriodTo: string = '00:00';
|
||||||
|
|
||||||
|
public runOnBattery: boolean = true;
|
||||||
|
public batteryLevelThreshold: number = 0;
|
||||||
|
|
||||||
public upgradeAutomatically: boolean = false;
|
public upgradeAutomatically: boolean = false;
|
||||||
public downloadUpgradePath: string = '';
|
public downloadUpgradePath: string = '';
|
||||||
|
|
||||||
|
|
|
@ -155,6 +155,12 @@ declare global {
|
||||||
getBatteryLevel: () => void;
|
getBatteryLevel: () => void;
|
||||||
onGetBatteryLevel: (callback: (event: any, level: number) => void) => void;
|
onGetBatteryLevel: (callback: (event: any, level: number) => void) => void;
|
||||||
unregisterOnGetBatteryLevel: () => void;
|
unregisterOnGetBatteryLevel: () => void;
|
||||||
|
|
||||||
|
isOnBatteryPower: () => void;
|
||||||
|
onIsOnBatteryPower: (callback: (event: any, onBattery: boolean) => void) => void;
|
||||||
|
unregisterOnIsOnBatteryPower: () => void;
|
||||||
|
onBattery: (callback: (event: any) => void) => void;
|
||||||
|
onAc: (callback: (event: any) => void) => void;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue