Outputs methods implementation

This commit is contained in:
everoddandeven 2024-10-12 16:36:15 +02:00
parent cd4ccd8c11
commit 8ed6bb7036
3 changed files with 244 additions and 50 deletions

View file

@ -12,6 +12,7 @@ import * as os from 'os';
const bz2 = require('unbzip2-stream');
let win: BrowserWindow | null = null;
let isHidden: boolean = false;
let isQuitting: boolean = false;
const args = process.argv.slice(1),
@ -45,7 +46,8 @@ function createWindow(): BrowserWindow {
const tray = new Tray(wdwIcon);
const trayMenu = Menu.buildFromTemplate(trayMenuTemplate);
tray.setToolTip('Monero Daemon');
tray.setContextMenu(trayMenu);
console.log(`createWindow(): icon = ${wdwIcon}`);
@ -89,10 +91,26 @@ function createWindow(): BrowserWindow {
win.loadURL(url.href);
}
tray.on('click', (event) => {
if (isHidden) {
win?.show();
isHidden = false;
}
else
{
win?.hide();
isHidden = true;
}
console.log("Clicked monero gui icon tray");
console.log(event);
});
win.on('close', (event) => {
if (!isQuitting) {
event.preventDefault();
win?.hide();
isHidden = true;
//event.returnValue = false;
}

View file

@ -10,26 +10,76 @@
</ul>
</div>
</div>
<div *ngIf="daemonRunning" class="tab-content" id="pills-tabContent">
<div class="tab-pane fade show active" id="pills-outputs-overview" role="tabpanel" aria-labelledby="pills-outputs-overview-tab" tabindex="0">
<table
[hidden]="getOutsOuts.length === 0"
id="outsTable"
data-toggle="outsTable"
data-toolbar="#toolbar"
data-height="460"
>
<thead>
<tr>
<th data-field="height">Height</th>
<th data-field="key">Key</th>
<th data-field="mask">Mask</th>
<th data-field="txId">Tx ID</th>
<th data-field="unlocked">Unlocked</th>
</tr>
</thead>
</table>
<div *ngIf="daemonRunning && !daemonStopping && !daemonRestarting" class="tab-content" id="pills-tabContent">
<div class="tab-pane fade show active" id="pills-outputs-get-outs" role="tabpanel" aria-labelledby="pills-outputs-get-outs-tab" tabindex="0">
<h4 class="mb-3">Get outputs</h4>
<div *ngIf="getOutsError !== ''" class="alert alert-danger d-flex align-items-center justify-content-center text-center" role="alert">
<h4><i class="bi bi-exclamation-triangle m-2"></i></h4>&nbsp;&nbsp;
<div>
{{getOutsError}}
</div>
</div>
<div [hidden]="!getOutsSuccess">
<table
id="outsTable"
data-toggle="outsTable"
data-toolbar="#toolbar"
data-paged="true"
data-height="460"
>
<thead>
<tr>
<th data-field="height">Height</th>
<th data-field="key">Key</th>
<th data-field="mask">Mask</th>
<th data-field="txId">Tx ID</th>
<th data-field="unlocked">Unlocked</th>
</tr>
</thead>
</table>
</div>
<div class="row g-5 p-2">
<div class="cold-md-7 col-lg-12">
<div class="row gy-3">
<div class="col-sm-12">
<form class="needs-validation" novalidate="">
<div class="row g-3">
<div class="col-12">
<label for="get-out-outs" class="form-label">Outputs</label>
<textarea type="text" class="form-control" id="get-out-outs" placeholder="[
{
'amount': number,
'index': number
}
]"
rows="15" cols="15" [(ngModel)]="getOutsJsonString" [ngModelOptions]="{standalone: true}"></textarea>
<small class="text-body-secondary">Array of outputs</small>
</div>
</div>
</form>
</div>
<div class="form-check form-switch col-md-6">
<label for="get-out-get-txid" class="form-check-label">Get Tx Id</label>
<input class="form-control form-check-input" type="checkbox" role="switch" id="get-out-get-txid" [checked]="getOutsGetTxId" [(ngModel)]="getOutsGetTxId" [ngModelOptions]="{standalone: true}">
<br>
<small class="text-body-secondary">If enabled, a <i>txid</i> will included for each output in the response</small>
</div>
</div>
</div>
</div>
<button *ngIf="!gettingOuts" class="w-100 btn btn-primary btn-lg" type="button" [disabled]="!validOuts" (click)="getOuts()">Get Outputs</button>
<button *ngIf="gettingOuts" class="w-100 btn btn-primary btn-lg" type="button" disabled>
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Getting Outputs
</button>
</div>
@ -41,8 +91,23 @@
</div>
</div>
<div *ngIf="getOutHistogramResult !== undefined" class="alert alert-success d-flex align-items-center justify-content-center text-center" role="alert">
<div [hidden]="getOutHistogramResult === undefined">
<table
id="outHistrogramsTable"
data-toggle="outHistogramsTable"
data-toolbar="#toolbar"
data-paged="true"
data-height="460"
>
<thead>
<tr>
<th data-field="amount">Amount</th>
<th data-field="base">Base</th>
<th data-field="startHeight">Start Height</th>
<th data-field="distributions">Distributions</th>
</tr>
</thead>
</table>
</div>
<div class="row g-5 p-2">
@ -97,7 +162,11 @@
</div>
</div>
<button class="w-100 btn btn-primary btn-lg" type="button" [disabled]="!validOutDistributionAmounts" (click)="getOutHistogram()">Get Output Histogram</button>
<button *ngIf="!gettingOutHistogram" class="w-100 btn btn-primary btn-lg" type="button" [disabled]="!validOutHistogramAmounts" (click)="getOutHistogram()">Get Output Histogram</button>
<button *ngIf="gettingOutHistogram" class="w-100 btn btn-primary btn-lg" type="button" disabled>
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Getting Output Histogram
</button>
</div>
<div class="tab-pane fade" id="pills-outputs-distribution" role="tabpanel" aria-labelledby="pills-outputs-distribution-tab" tabindex="0">
@ -108,8 +177,23 @@
</div>
</div>
<div *ngIf="getOutDistributionResult !== undefined" class="alert alert-success d-flex align-items-center justify-content-center text-center" role="alert">
<div [hidden]="getOutDistributionResult === undefined">
<table
id="outDistributionsTable"
data-toggle="outDistributionsTable"
data-toolbar="#toolbar"
data-paged="true"
data-height="460"
>
<thead>
<tr>
<th data-field="amount">Amount</th>
<th data-field="base">Base</th>
<th data-field="startHeight">Start Height</th>
<th data-field="distributions">Distributions</th>
</tr>
</thead>
</table>
</div>
<div class="row g-5 p-2">
@ -158,7 +242,11 @@
</div>
</div>
<button class="w-100 btn btn-primary btn-lg" type="button" [disabled]="!validOutDistributionAmounts" (click)="getOutDistribution()">Get Out Distribution</button>
<button *ngIf="!gettingOutDistribution" class="w-100 btn btn-primary btn-lg" type="button" [disabled]="!validOutDistributionAmounts" (click)="getOutDistribution()">Get Out Distribution</button>
<button *ngIf="gettingOutDistribution" class="w-100 btn btn-primary btn-lg" type="button" disabled>
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Getting Output Distribution
</button>
</div>
<div class="tab-pane fade" id="pills-is-key-image-spent" role="tabpanel" aria-labelledby="pills-is-key-image-spent-tab" tabindex="0">

View file

@ -3,6 +3,7 @@ import { NavbarLink } from '../../shared/components/navbar/navbar.model';
import { DaemonService } from '../../core/services/daemon/daemon.service';
import { NavbarService } from '../../shared/components/navbar/navbar.service';
import { HistogramEntry, Output, OutputDistribution } from '../../../common';
import { DaemonDataService } from '../../core/services';
@Component({
selector: 'app-outputs',
@ -12,10 +13,23 @@ import { HistogramEntry, Output, OutputDistribution } from '../../../common';
export class OutputsComponent implements AfterViewInit {
public readonly navbarLinks: NavbarLink[];
public daemonRunning: boolean = false;
public get daemonRunning(): boolean {
return this.daemonData.running;
}
public get daemonStopping(): boolean {
return this.daemonData.stopping;
}
public get daemonRestarting(): boolean {
return this.daemonService.restarting;
}
public getOutsJsonString: string = '';
public getOutsGetTxId: boolean = false;
public getOutsError: string = '';
public getOutsSuccess: boolean = false;
public gettingOuts: boolean = false;
public keyImagesJsonString: string = '';
public isKeyImageSpentError: string = '';
@ -59,6 +73,15 @@ export class OutputsComponent implements AfterViewInit {
public getOutHistogramError: string = '';
public gettingOutHistogram: boolean = false;
public get getOutHistogramAmounts(): number[] {
if (!this.validOutHistogramAmounts) {
return [];
}
return <number[]>JSON.parse(this.getOutHistogramAmountsJsonString);
}
public gettingOutDistribution: boolean = false;
public getOutDistributionAmountsJsonString: string = '';
public getOutDistributionFromHeight: number = 0;
public getOutDistributionToHeight: number = 0;
@ -74,20 +97,13 @@ export class OutputsComponent implements AfterViewInit {
return <number[]>JSON.parse(this.getOutDistributionAmountsJsonString);
}
constructor(private daemonService: DaemonService, private navbarService: NavbarService, private ngZone: NgZone) {
constructor(private daemonData: DaemonDataService, private daemonService: DaemonService, private navbarService: NavbarService, private ngZone: NgZone) {
this.navbarLinks = [
new NavbarLink('pills-outputs-overview-tab', '#pills-outputs-overview', 'outputs-overview', false, 'Overview'),
new NavbarLink('pills-outputs-get-outs-tab', '#pills-outputs-get-outs', 'outputs-get-outs', false, 'Get Outs'),
new NavbarLink('pills-outputs-histogram-tab', '#pills-outputs-histogram', 'outputs-histogram', false, 'Histogram'),
new NavbarLink('pills-outputs-distribution-tab', '#pills-outputs-distribution', 'outputs-distribution', false, 'Distribution'),
new NavbarLink('pills-is-key-image-spent-tab', '#pills-is-key-image-spent', 'is-key-image-spent', false, 'Is Key Image Spent')
];
this.daemonService.isRunning().then((value) => {
this.daemonRunning = value;
}).catch((error: any) => {
console.error(error);
this.daemonRunning = false;
})
}
public ngAfterViewInit(): void {
@ -95,15 +111,23 @@ export class OutputsComponent implements AfterViewInit {
this.ngZone.run(async () => {
//const $ = require('jquery');
//const bootstrapTable = require('bootstrap-table');
const $table = $('#outsTable');
$table.bootstrapTable({
});
$table.bootstrapTable('refreshOptions', {
const options = {
classes: 'table table-bordered table-hover table-dark table-striped'
});
$table.bootstrapTable('showLoading');
};
const $table = $('#outsTable');
$table.bootstrapTable({});
const $distributionsTable = $('#outDistributionsTable');
$distributionsTable.bootstrapTable({});
const $histogramTable = $('#outHistrogramsTable');
$histogramTable.bootstrapTable({});
$table.bootstrapTable('refreshOptions', options);
$distributionsTable.bootstrapTable('refreshOptions', options);
$histogramTable.bootstrapTable('refreshOptions', options);
await this.load();
}).then().catch((error: any) => {
console.error(error);
@ -132,6 +156,10 @@ export class OutputsComponent implements AfterViewInit {
return false;
}
if (_outs.length == 0) {
return false;
}
_outs.forEach((_out) => Output.parse(_out));
return true;
@ -141,13 +169,25 @@ export class OutputsComponent implements AfterViewInit {
}
public async getOuts() {
const $table = $('#outsTable');
$table.bootstrapTable({});
this.gettingOuts = true;
const outs = await this.daemonService.getOuts(this.getOutsOuts, this.getOutsGetTxId);
try {
const $table = $('#outsTable');
$table.bootstrapTable({});
const outs = await this.daemonService.getOuts(this.getOutsOuts, this.getOutsGetTxId);
$table.bootstrapTable('load', outs);
$table.bootstrapTable('load', outs)
this.getOutsError = '';
this.getOutsSuccess = true;
}
catch(error: any) {
console.error(error);
this.getOutsError = `${error}`;
this.getOutsSuccess = false;
}
this.gettingOuts = false;
}
public get validOutDistributionAmounts(): boolean {
@ -169,7 +209,28 @@ export class OutputsComponent implements AfterViewInit {
}
}
public get validOutHistogramAmounts(): boolean {
try {
const amounts: number[] = JSON.parse(this.getOutHistogramAmountsJsonString);
if(!Array.isArray(amounts)) {
return false;
}
amounts.forEach((amount) => {
if (typeof amount != 'number' || amount <= 0) throw new Error("");
})
return true;
}
catch(error) {
return false;
}
}
public async getOutDistribution(): Promise<void> {
this.gettingOutDistribution = true;
try
{
const amounts = this.getOutDistributionAmounts;
@ -178,15 +239,42 @@ export class OutputsComponent implements AfterViewInit {
const toHeight = this.getOutDistributionToHeight;
this.getOutDistributionResult = await this.daemonService.getOutputDistribution(amounts, cumulative, fromHeight, toHeight);
this.loadOutDistributionTable();
this.getOutDistributionError = '';
}
catch(error: any) {
this.getOutDistributionError = `${error}`;
this.getOutDistributionResult = undefined;
}
this.gettingOutDistribution = false;
}
private loadOutDistributionTable(): void {
const $table = $('#outDistributionsTable');
$table.bootstrapTable('load', this.getOutDistributionResult);
}
private loadOutHistogramTable(): void {
const $table = $('#outHistogramsTable');
$table.bootstrapTable('load', this.getOutHistogramResult);
}
public async getOutHistogram(): Promise<void> {
this.gettingOutHistogram = true;
try {
this.getOutHistogramResult = await this.daemonService.getOutputHistogram(this.getOutHistogramAmounts, this.getOutHistogramMinCount, this.getOutHistogramMaxCount, this.getOutHistogramUnlocked, this.getOutHistogramRecentCutoff);
this.getOutHistogramError = '';
this.loadOutHistogramTable();
}
catch(error: any) {
console.error(error);
this.getOutHistogramError = `${error}`;
this.getOutHistogramResult = undefined;
}
this.gettingOutHistogram = false;
}
public async isKeyImageSpent(): Promise<void> {