Skip to content

Commit

Permalink
4.10.0 (#130)
Browse files Browse the repository at this point in the history
* 4.10.0

* 4.10.0

* 4.10.0

* 4.10.0

* 4.10.0
  • Loading branch information
dev-ptera authored Feb 11, 2024
1 parent ea2ff08 commit 636e2aa
Show file tree
Hide file tree
Showing 16 changed files with 310 additions and 22 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
# Change Log

## v4.10.0 (February 10, 2024)

### Added

- Added toggle to enable / disable automatic receiving, defaulting to Enabled.

## v4.9.0 (February 5, 2024)

### Added

- Added ability to select which transactions to receive.
- Added ability to select which transactions to receive from within Receive transaction overlay.

## v4.8.0 (January 7, 2024)

Expand Down
17 changes: 10 additions & 7 deletions cypress/e2e/account_actions.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,27 @@ describe('Account Actions', () => {
cy.reload();
cy.intercept(root).as('home');
cy.visit(root);
localStorage.setItem(
'bananostand_userAutoReceiveTransactions',
'false'
); // Disable auto-receive for account action tests.
cy.wait('@home'); // once the route resolves, cy.wait will resolve as well
cy.importAccount(LOW_FUND_SEED);
dashboardRobot.checkDashboardExists().clickAccountNumber(0);
accountRobot.checkAccountPageExists().checkTransactionsLoaded();
});

describe('Filtering', () => {
it('should open filter overlay (desktop)', () => {
it('should open/close filter overlay (desktop)', () => {
accountRobot.clickFilterButtonDesktop();
overlayRobot.checkFilterOverlayExists();
overlayRobot
.checkFilterOverlayExists()
.clickCloseFilterButton()
.checkFilterOverlayNotExists();
});
it('should open filter overlay (mobile)', () => {
it.only('should open/close filter overlay (mobile)', () => {
cy.viewport('iphone-6');
accountRobot.clickAccountActions().clickFilterButtonMobile();
overlayRobot.checkFilterOverlayExists();
});
it('should close the filter overlay', () => {
accountRobot.clickFilterButtonDesktop();
overlayRobot
.checkFilterOverlayExists()
.clickCloseFilterButton()
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "thebananostand",
"version": "4.9.0",
"version": "4.10.0",
"scripts": {
"ng": "ng",
"start": "ng serve --open --host 0.0.0.0",
Expand Down
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ import { AddRpcOverlayComponent } from '@app/overlays/actions/add-rpc/add-rpc.co
import { AddRpcDialogComponent } from '@app/overlays/dialogs/add-rpc/add-rpc-dialog.component';
import { AddRpcBottomSheetComponent } from '@app/overlays/bottom-sheet/add-rpc/add-rpc-bottom-sheet.component';
import { initializeApp } from './app.initializer';
import { ReceiveSnackbarComponent } from '@app/overlays/snackbar/receive-snackbar.component';

LOAD_WASM().subscribe((res: any) => console.log('WASM ngx-scanner-qrcode loaded', res));

Expand Down Expand Up @@ -164,6 +165,7 @@ LOAD_WASM().subscribe((res: any) => console.log('WASM ngx-scanner-qrcode loaded'
TransactionComponent,
AccountTableComponent,
AccountActionsComponent,
ReceiveSnackbarComponent,
],
imports: [
AppRoutingModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
<div class="overlay-header">Change Password</div>
<div class="overlay-body">
<div style="display: flex; align-items: center">
<mat-icon class="secondary-text" style="padding-right: 16px">info</mat-icon>
<mat-icon class="secondary-text" style="overflow: visible">info</mat-icon>
<span style="margin-left: 16px" class="mat-body-1"
>You will be logged out after changing your password.</span
>
Expand Down
2 changes: 1 addition & 1 deletion src/app/overlays/dialogs/send/send-dialog.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { SendOverlayData } from '@app/overlays/actions/send/send.component';

@Component({
selector: 'app-change-rep-dialog',
selector: 'app-send-dialog',
template: ` <app-send-overlay [data]="data" (closeWithHash)="closeDialog($event)"></app-send-overlay> `,
})
export class SendDialogComponent {
Expand Down
15 changes: 15 additions & 0 deletions src/app/overlays/snackbar/receive-snackbar.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.container {
justify-content: space-between;
display: flex;
align-items: center;
}

.info-icon-container {
$width: 48px;
max-width: $width;
width: $width;
margin-left: 8px;
display: flex;
align-items: center;
justify-content: flex-start;
}
119 changes: 119 additions & 0 deletions src/app/overlays/snackbar/receive-snackbar.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { Component } from '@angular/core';
import { ReceiveService } from '@app/services/receive.service';
import { scan, takeWhile, tap, timer } from 'rxjs';
import { AppStateService } from '@app/services/app-state.service';
import { MatSnackBar } from '@angular/material/snack-bar';
import {
REFRESH_DASHBOARD_ACCOUNTS,
SNACKBAR_CLOSE_ACTION_TEXT,
SNACKBAR_DURATION,
} from '@app/services/wallet-events.service';

@Component({
selector: 'app-receive-snackbar',
styleUrls: [`receive-snackbar.component.scss`],
template: `
<ng-template #closeButton>
<button mat-button (click)="close()" style="margin-right: -8px;" color="primary">
{{ isCompleted || showError ? closeText : 'Cancel' }}
</button>
</ng-template>
<div *ngIf="showError" class="container">
<div>An auto-receiving error occurred.</div>
<ng-template [ngTemplateOutlet]="closeButton"></ng-template>
</div>
<ng-container *ngIf="!showError">
<div *ngIf="isCompleted" class="container">
<div style="display: flex; align-items: center">
<div class="info-icon-container">
<mat-icon class="info-icon">verified</mat-icon>
</div>
<div>{{ receivedAmount | appComma }} BAN received!</div>
</div>
<ng-template [ngTemplateOutlet]="closeButton"></ng-template>
</div>
<ng-container *ngIf="!isCompleted">
<div *ngIf="timeUntilAutoReceiveStarts !== 0" class="container">
<div style="display: flex; align-items: center">
<div class="info-icon-container">
<mat-icon class="info-icon">download</mat-icon>
</div>
<div>Auto-receiving in {{ timer$ | async }}...</div>
</div>
<ng-template [ngTemplateOutlet]="closeButton"></ng-template>
</div>
<div *ngIf="timeUntilAutoReceiveStarts === 0" class="container">
<div style="display: flex; align-items: center;">
<div class="info-icon-container">
<mat-spinner diameter="22"></mat-spinner>
</div>
<div>Receiving block No. {{ currentBlockNumberReceiving }} of {{ maxBlocks }}...</div>
</div>
<ng-template [ngTemplateOutlet]="closeButton"></ng-template>
</div>
</ng-container>
</ng-container>
`,
})
export class ReceiveSnackbarComponent {
timeBetweenTicks = 1000;
timeUntilAutoReceiveStarts = 5;
blocks = [];
showError = false;
isCompleted = false;
closeText = SNACKBAR_CLOSE_ACTION_TEXT;

constructor(
private readonly _snackbar: MatSnackBar,
private readonly _receiveService: ReceiveService,
private readonly _appStateService: AppStateService
) {}

ngOnInit(): void {
this.blocks = this._appStateService.getAllReceivableBlocks();
if (this.blocks.length === 0) {
return;
}
}

close(): void {
this._receiveService.stopReceive();
this._snackbar.dismiss();
}

get maxBlocks(): number {
return this._receiveService.maxBlocks;
}

get currentBlockNumberReceiving(): number {
return this._receiveService.currentBlockNumberReceiving;
}

get receivedAmount(): number {
return this._receiveService.receivedAmount;
}

timer$ = timer(0, this.timeBetweenTicks).pipe(
// eslint-disable-next-line no-param-reassign
scan((acc) => --acc, this.timeUntilAutoReceiveStarts),
tap((x) => {
this.timeUntilAutoReceiveStarts = x;
if (this.timeUntilAutoReceiveStarts === 0) {
this._receiveService
.receiveTransaction(this.blocks)
.catch(() => {
this.showError = true;
})
.finally(() => {
this.isCompleted = true;
REFRESH_DASHBOARD_ACCOUNTS.next();
setTimeout(() => {
this._snackbar.dismiss();
}, SNACKBAR_DURATION);
});
}
}),
takeWhile((x) => x >= 0)
);
}
10 changes: 1 addition & 9 deletions src/app/pages/dashboard/dashboard.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,15 +162,7 @@ export class DashboardComponent {
}

openReceiveAllOverlay(): void {
const blocks = [];
for (const account of this.store.accounts) {
for (const block of account.pending) {
blocks.push({
accountIndex: account.index,
...block,
});
}
}
const blocks = this._appStateService.getAllReceivableBlocks();
const data: ReceiveOverlayData = { blocks: blocks, refreshDashboard: true };
if (this.vp.sm) {
setTimeout(() => {
Expand Down
18 changes: 18 additions & 0 deletions src/app/pages/settings/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
REMOVE_CUSTOM_RPC_NODE_BY_INDEX,
SELECT_LOCALIZATION_CURRENCY,
SELECTED_RPC_DATASOURCE_CHANGE,
USER_TOGGLE_AUTO_RECEIVE,
} from '@app/services/wallet-events.service';
import { MatRadioChange } from '@angular/material/radio';
import { CurrencyConversionService } from '@app/services/currency-conversion.service';
Expand All @@ -21,6 +22,7 @@ import { MatSelectChange } from '@angular/material/select';
import { UntilDestroy } from '@ngneat/until-destroy';
import { AddRpcBottomSheetComponent } from '@app/overlays/bottom-sheet/add-rpc/add-rpc-bottom-sheet.component';
import { AddRpcDialogComponent } from '@app/overlays/dialogs/add-rpc/add-rpc-dialog.component';
import { MatSlideToggleChange } from '@angular/material/slide-toggle';

@Pipe({ name: 'available' })
export class DatasourceAvailablePipe implements PipeTransform {
Expand Down Expand Up @@ -227,6 +229,16 @@ export class DatasourceAvailablePipe implements PipeTransform {
type="number"
/>
</mat-form-field>
<mat-divider></mat-divider>
<div class="mat-overline" style="margin-top: 16px">Auto-Receive Incoming Transactions</div>
<div class="mat-body-2" style="margin-bottom: 24px">
Incoming transactions will be automatically received when the wallet is unlocked.
</div>
<mat-slide-toggle
(change)="toggleAutoReceiveIncomingTransactions($event)"
[checked]="isEnableAutoReceiveFeature"
>Enable</mat-slide-toggle
>
</mat-card>
</div>
</div>
Expand All @@ -239,6 +251,7 @@ export class SettingsPageComponent implements OnInit {
selectedSpyglassApi: Datasource;
selectedCurrencyCode: string;
minimumThreshold: number;
isEnableAutoReceiveFeature: boolean;

constructor(
public vp: ViewportService,
Expand All @@ -252,6 +265,7 @@ export class SettingsPageComponent implements OnInit {
) {
this._appStateService.store.subscribe((data) => {
this.selectedCurrencyCode = data.localCurrencyCode;
this.isEnableAutoReceiveFeature = data.isEnableAutoReceiveFeature;
});
SELECTED_RPC_DATASOURCE_CHANGE.subscribe((source) => {
this.selectedRpcSource = source;
Expand Down Expand Up @@ -288,6 +302,10 @@ export class SettingsPageComponent implements OnInit {
REMOVE_CUSTOM_RPC_NODE_BY_INDEX.next(index);
}

toggleAutoReceiveIncomingTransactions(e: MatSlideToggleChange): void {
USER_TOGGLE_AUTO_RECEIVE.next(e.checked);
}

clearStorage(): void {
REMOVE_ALL_WALLET_DATA.next();
void this._router.navigate(['/']);
Expand Down
18 changes: 18 additions & 0 deletions src/app/services/app-state.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AccountOverview } from '@app/types/AccountOverview';
import { LocalStorageWallet } from '@app/services/wallet-storage.service';
import { BehaviorSubject, Subject } from 'rxjs';
import { PriceData } from '@app/types/PriceData';
import { ReceivableTx } from '@app/types/ReceivableTx';

export type AppStore = {
/** Loaded ledger accounts, their rep, & respective balances. */
Expand Down Expand Up @@ -41,6 +42,8 @@ export type AppStore = {
preferredDashboardView: 'card' | 'table';
/** Custom RPC nodes **/
customRpcNodeURLs: string[];
/** User wants to receive funds automatically whenever wallet is opened. **/
isEnableAutoReceiveFeature: boolean;
};

@Injectable({
Expand Down Expand Up @@ -75,6 +78,7 @@ export class AppStateService {
isLoadingAccounts: true,
preferredDashboardView: undefined,
customRpcNodeURLs: [],
isEnableAutoReceiveFeature: true,
});

appLocalStorage = new Subject<{
Expand All @@ -86,5 +90,19 @@ export class AppStateService {
preferredDashboardView: string;
idleTimeoutMinutes: number;
customRpcNodeURLs: string[];
isEnableAutoReceiveFeature: boolean;
}>();

getAllReceivableBlocks(): Array<ReceivableTx & { accountIndex: number }> {
const blocks = [];
for (const account of this.store.getValue().accounts) {
for (const block of account.pending) {
blocks.push({
accountIndex: account.index,
...block,
});
}
}
return blocks;
}
}
Loading

0 comments on commit 636e2aa

Please sign in to comment.