1
0
Fork 0
forked from lthn/blockchain

Merge branch 'develop' into release

This commit is contained in:
cryptozoidberg 2020-11-10 19:16:51 +03:00
commit 28b3250b04
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
20 changed files with 927 additions and 255 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -3,6 +3,9 @@ import {Transaction} from './transaction.model';
import {BigNumber} from 'bignumber.js';
export class Wallet {
stop_paginate: boolean;
open_from_exist: boolean;
updated = false;
wallet_id: number;
name: string;
pass: string;

View file

@ -210,7 +210,16 @@ export class BackendService {
if (typeof Result === 'object' && 'error_code' in Result && Result.error_code !== 'OK' && Result.error_code !== 'TRUE' && Result.error_code !== 'FALSE') {
if (core_busy) {
setTimeout( () => {
this.runCommand(command, params, callback);
// this is will avoid update data when user
// on other wallet after CORE_BUSY (blink of data)
if (command !== 'get_recent_transfers') {
this.runCommand(command, params, callback);
} else {
const current_wallet_id = this.variablesService.currentWallet.wallet_id;
if (current_wallet_id === params.wallet_id) {
this.runCommand(command, params, callback);
}
}
}, 50);
} else {
this.informerRun(Result.error_code, params, command);
@ -234,6 +243,9 @@ export class BackendService {
private runCommand(command, params?, callback?) {
if (this.backendObject) {
if (command === 'get_recent_transfers') {
this.variablesService.get_recent_transfers = true;
}
const Action = this.backendObject[command];
if (!Action) {
BackendService.Debug(0, 'Run Command Error! Command "' + command + '" don\'t found in backendObject');
@ -241,6 +253,9 @@ export class BackendService {
const that = this;
params = (typeof params === 'string') ? params : JSONBigNumber.stringify(params);
if (params === undefined || params === '{}') {
if (command === 'get_recent_transfers') {
this.variablesService.get_recent_transfers = false;
}
Action(function (resultStr) {
that.commandDebug(command, params, resultStr);
return that.backendCallback(resultStr, params, callback, command);
@ -641,14 +656,14 @@ export class BackendService {
}
}
getRecentTransfers( id, offset, count,exclude_mining_txs, callback) {
getRecentTransfers( id, offset, count, exclude_mining_txs, callback) {
const params = {
wallet_id: id,
offset: offset,
count: count,
exclude_mining_txs: exclude_mining_txs
};
this.runCommand('get_recent_transfers', params, callback);
this.runCommand('get_recent_transfers', params, callback);
}
getPoolInfo(callback) {

View file

@ -2,6 +2,7 @@ import { Injectable, NgZone } from '@angular/core';
import { VariablesService } from './variables.service';
import { PaginationStore } from './pagination.store';
import * as _ from 'lodash';
import {Store} from 'store';
@Injectable({
providedIn: 'root',
@ -11,17 +12,15 @@ export class PaginationService {
constructor(
private variables: VariablesService,
private ngZone: NgZone,
private paginationStore: PaginationStore
private paginationStore: PaginationStore,
) { }
paginate(currentPage = 1) {
if (currentPage < 1) {
currentPage = 1;
} else if (currentPage > this.variables.currentWallet.totalPages) {
currentPage = this.variables.currentWallet.totalPages;
}
let startPage: number, endPage: number;
if (this.variables.currentWallet.totalPages <= this.variables.maxPages) {
startPage = 1;
@ -48,12 +47,13 @@ export class PaginationService {
});
}
getOffset() {
getOffset(walletID) {
const mining = this.variables.currentWallet.exclude_mining_txs;
const currentPage = (this.variables.currentWallet.currentPage);
let offset = ((currentPage - 1) * this.variables.count);
if (!mining) { return offset; }
const pages = this.paginationStore.value;
const value = this.paginationStore.value;
const pages = value.filter(item => item.walletID === walletID);
if (pages && pages.length) {
const max = _.maxBy(pages, 'page');
const isForward = this.paginationStore.isForward(pages, currentPage);
@ -66,4 +66,37 @@ export class PaginationService {
}
return offset;
}
calcPages(data) {
if (data.total_history_items && (data && data.history)) {
this.variables.currentWallet.totalPages = Math.ceil( data.total_history_items / this.variables.count);
this.variables.currentWallet.totalPages > this.variables.maxPages
? this.variables.currentWallet.pages = new Array(5).fill(1).map((value, index) => value + index)
: this.variables.currentWallet.pages =
new Array(this.variables.currentWallet.totalPages).fill(1).map((value, index) => value + index);
} else if (this.variables.currentWallet.restore) {
this.variables.currentWallet.totalPages = Math.ceil( data.history.length / this.variables.count);
this.variables.currentWallet.totalPages > this.variables.maxPages
? this.variables.currentWallet.pages = new Array(5).fill(1).map((value, index) => value + index)
: this.variables.currentWallet.pages =
new Array(this.variables.currentWallet.totalPages).fill(1).map((value, index) => value + index);
}
}
prepareHistory(data, status) {
if (status && (data && data.total_history_items)) {
this.variables.currentWallet.history.splice(0, this.variables.currentWallet.history.length);
this.ngZone.run(() => {
this.paginate(this.variables.currentWallet.currentPage);
if (data.history.length !== 0) {
this.variables.currentWallet.restore = false;
this.variables.currentWallet.total_history_item = data.total_history_items;
this.variables.currentWallet.prepareHistory(data.history);
if (this.variables.currentWallet.currentPage === 1 && data.unconfirmed) {
this.variables.currentWallet.prepareHistory(data.unconfirmed);
}
}
});
}
}
}

View file

@ -1,20 +1,17 @@
import {Injectable} from '@angular/core';
import {Observable, BehaviorSubject} from 'rxjs';
import {VariablesService} from './variables.service';
import * as _ from 'lodash';
export interface Pages {
page: number;
page: number;
offset: number;
walletID: number;
}
@Injectable({
providedIn: 'root'
})
export class PaginationStore {
constructor(
private variablesService: VariablesService
) {
}
) {}
private subject = new BehaviorSubject<Pages[]>(null);
pages$: Observable<Pages[]> = this.subject.asObservable();
@ -22,13 +19,13 @@ export class PaginationStore {
const max = _.maxBy(pages, 'page');
return !max || max.page < currentPage || max.page === currentPage;
}
setPage(pageNumber: number, offset: number) {
const pages = this.subject.getValue();
setPage(pageNumber: number, offset: number, walletID: number) {
let newPages: Pages[] = [];
const pages = this.subject.getValue();
if (pages && pages.length) {
newPages = pages.slice(0);
}
newPages.push({page: pageNumber, offset});
newPages.push({page: pageNumber, offset, walletID});
this.subject.next(newPages);
}

View file

@ -11,7 +11,9 @@ import {BigNumber} from 'bignumber.js';
providedIn: 'root'
})
export class VariablesService {
public request_on_in = {};
public stop_paginate = {};
public sync_started = false;
public digits = 12;
public appPass = '';
public appLogin = false;
@ -36,6 +38,7 @@ export class VariablesService {
progress_value: 0,
progress_value_text: '0'
};
public get_recent_transfers = false; // avoid of execute function before collback complete
public default_fee = '0.010000000000';
public default_fee_big = new BigNumber('10000000000');
@ -71,7 +74,7 @@ export class VariablesService {
public newContact: Contact = {name: null, address: null, notes: null};
public pattern = '^[a-zA-Z0-9_.\\\]\*\|\~\!\?\@\#\$\%\^\&\+\{\}\(\)\<\>\:\;\"\'\-\=\/\,\[\\\\]*$';
public after_sync_request: any = {};
getExpMedTsEvent = new BehaviorSubject(null);
getHeightAppEvent = new BehaviorSubject(null);
getHeightMaxEvent = new BehaviorSubject(null);
@ -162,6 +165,15 @@ export class VariablesService {
return null;
}
getNotLoadedWallet() {
for (let i = 0; i < this.wallets.length; i++) {
if (!this.wallets[i].loaded) {
return this.wallets[i];
}
}
return null;
}
startCountdown() {
this.idle.within(this.settings.appLockTime).start();
}

View file

@ -9,6 +9,7 @@ import {IntToMoneyPipe} from './_helpers/pipes/int-to-money.pipe';
import {BigNumber} from 'bignumber.js';
import {ModalService} from './_helpers/services/modal.service';
import {UtilsService} from './_helpers/services/utils.service';
import {Store} from 'store';
@Component({
selector: 'app-root',
@ -40,7 +41,8 @@ export class AppComponent implements OnInit, OnDestroy {
private ngZone: NgZone,
private intToMoneyPipe: IntToMoneyPipe,
private modalService: ModalService,
private utilsService: UtilsService
private utilsService: UtilsService,
private store: Store
) {
translate.addLangs(['en', 'fr', 'de', 'it', 'pt']);
translate.setDefaultLang('en');
@ -129,7 +131,6 @@ export class AppComponent implements OnInit, OnDestroy {
const wallet_state = data.wallet_state;
const is_mining = data.is_mining;
const wallet = this.variablesService.getWallet(data.wallet_id);
// 1-synch, 2-ready, 3 - error
if (wallet) {
this.ngZone.run(() => {
@ -157,21 +158,15 @@ export class AppComponent implements OnInit, OnDestroy {
if (wallet) {
this.ngZone.run(() => {
wallet.progress = (data.progress < 0) ? 0 : ((data.progress > 100) ? 100 : data.progress);
if (!this.variablesService.sync_started) {
this.variablesService.sync_started = true;
}
this.addToStore(wallet, true); // subscribe on data
if (wallet.progress === 0) {
wallet.loaded = false;
} else if (wallet.progress === 100) {
wallet.loaded = true;
if (wallet.total_history_item) {
wallet.totalPages = Math.ceil( wallet.total_history_item / this.variablesService.count);
wallet.totalPages > this.variablesService.maxPages
? wallet.pages = new Array(5).fill(1).map((value, index) => value + index)
: wallet.pages = new Array(wallet.totalPages).fill(1).map((value, index) => value + index);
} else if (wallet.restore) {
wallet.totalPages = Math.ceil( wallet.history.length / this.variablesService.count);
wallet.totalPages > this.variablesService.maxPages
? wallet.pages = new Array(5).fill(1).map((value, index) => value + index)
: wallet.pages = new Array(wallet.totalPages).fill(1).map((value, index) => value + index);
}
this.addToStore(wallet, false);
}
});
}
@ -722,6 +717,28 @@ export class AppComponent implements OnInit, OnDestroy {
}
}
addToStore(wallet, boolean) {
const value = this.store.value.sync;
if (value && value.length) {
const sync = value.filter(item => item.wallet_id === wallet.wallet_id);
if (sync && sync.length) {
const result = value.map(item => {
if (item.wallet_id === wallet.wallet_id) {
return {sync: boolean, wallet_id: wallet.wallet_id};
} else {
return item;
}
});
this.store.set('sync', result);
} else {
value.push({sync: boolean, wallet_id: wallet.wallet_id});
this.store.set('sync', value);
}
} else {
this.store.set('sync', [{sync: boolean, wallet_id: wallet.wallet_id}]);
}
}
ngOnDestroy() {
if (this.intervalUpdateContractsState) {
clearInterval(this.intervalUpdateContractsState);

View file

@ -37,6 +37,11 @@ import { BackendService } from './_helpers/services/backend.service';
import { ModalService } from './_helpers/services/modal.service';
import { PaginationStore } from './_helpers/services/pagination.store';
// SERVICES
// Feature module
import { Store } from 'store';
// Feature module
import { MoneyToIntPipe } from './_helpers/pipes/money-to-int.pipe';
import { IntToMoneyPipe } from './_helpers/pipes/int-to-money.pipe';
import { HistoryTypeMessagesPipe } from './_helpers/pipes/history-type-messages.pipe';
@ -146,6 +151,7 @@ export function highchartsFactory() {
ContextMenuModule.forRoot()
],
providers: [
Store,
BackendService,
ModalService,
PaginationStore,

View file

@ -125,10 +125,12 @@ export class OpenWalletModalComponent implements OnInit {
}
skipWallet() {
if (this.wallets.length) {
this.wallets.splice(0, 1);
this.ngOnInit();
}
this.ngZone.run(() => {
if (this.wallets.length) {
this.wallets.splice(0, 1);
this.ngOnInit();
}
});
}
}

View file

@ -98,6 +98,7 @@ export class OpenWalletComponent implements OnInit, OnDestroy {
);
new_wallet.alias = this.backend.getWalletAlias(new_wallet.address);
new_wallet.currentPage = 1;
new_wallet.open_from_exist = true;
new_wallet.exclude_mining_txs = false;
new_wallet.is_auditable = open_data['wi'].is_auditable;
new_wallet.is_watch_only = open_data['wi'].is_watch_only;

View file

@ -121,6 +121,8 @@ export class RestoreWalletComponent implements OnInit {
}
runWallet() {
// add flag when wallet was restored form seed
this.variablesService.after_sync_request[this.wallet.id] = true;
let exists = false;
this.variablesService.wallets.forEach((wallet) => {
if (wallet.address === this.variablesService.opening_wallet.address) {

View file

@ -3,7 +3,7 @@
<h3>{{ 'SIDEBAR.TITLE' | translate }}</h3><button (click)="goMainPage()">{{ 'SIDEBAR.ADD_NEW' | translate }}</button>
</div>
<div class="sidebar-accounts-list scrolled-content">
<div class="sidebar-account" *ngFor="let wallet of variablesService.wallets" [class.active]="wallet?.wallet_id === walletActive" [routerLink]="['/wallet/' + wallet.wallet_id + '/history']">
<div class="sidebar-account" *ngFor="let wallet of variablesService.wallets" [class.active]="wallet?.wallet_id === walletActive" [routerLink]="['/wallet/' + wallet.wallet_id + '/history']" [queryParams]="{sidenav: true}">
<div class="wallet-type" (click)="goToAuditableWalletHelpPage($event)">
<div class="content auditable" *ngIf="wallet.is_auditable && !wallet.is_watch_only">
Auditable

View file

@ -51,20 +51,39 @@
<div *ngIf="activeTab === 'history'" class="pagination-wrapper">
<div class="pagination">
<div>
<button [disabled]="variablesService.currentWallet.currentPage === 1" (click)="setPage(variablesService.currentWallet.currentPage - 1)"><</button>
<button
[ngClass]="{'disabled': sync_started || wallet}"
[disabled]="variablesService.currentWallet.currentPage === 1 || sync_started || wallet"
(click)="setPage(variablesService.currentWallet.currentPage - 1)">
<
</button>
<ng-container *ngIf="!mining">
<button *ngFor="let page of variablesService.currentWallet.pages" [ngClass]="{ 'active': variablesService.currentWallet.currentPage === page }"
<button [disabled]="sync_started || wallet"
*ngFor="let page of variablesService.currentWallet.pages"
[ngClass]="{ 'active': variablesService.currentWallet.currentPage === page,'disabled': sync_started || wallet }"
(click)="setPage(page)">{{page}}</button>
</ng-container>
<ng-container *ngIf="mining">
<button [ngClass]="{ 'active': variablesService.currentWallet.currentPage }"
(click)="setPage(variablesService.currentWallet.currentPage)">{{variablesService.currentWallet.currentPage}}</button>
<button [ngClass]="{ 'active': variablesService.currentWallet.currentPage, 'disabled': sync_started || wallet}"
[disabled]="stop_paginate || sync_started || wallet"
(click)="setPage(variablesService.currentWallet.currentPage)">
{{variablesService.currentWallet.currentPage}}
</button>
</ng-container>
<button [disabled]="variablesService.currentWallet.currentPage === variablesService.currentWallet.totalPages" (click)="setPage(variablesService.currentWallet.currentPage + 1)">></button>
<button
[disabled]="stop_paginate || sync_started || wallet"
[ngClass]="{'disabled': sync_started || wallet}"
(click)="setPage(variablesService.currentWallet.currentPage + 1)">
>
</button>
</div>
<div class="mining-transaction-switch">
<span class="switch-text">Hide mining transactions</span>
<div class="switch" (click)="toggleMiningTransactions(); $event.stopPropagation()">
<div class="switch" [ngClass]="{'disabled': sync_started || wallet}" (click)="toggleMiningTransactions(); $event.stopPropagation()">
<span class="option" *ngIf="mining">{{ 'STAKING.SWITCH.ON' | translate }}</span>
<span class="circle" [class.on]="mining" [class.off]="!mining"></span>
<span class="option" *ngIf="!mining">{{ 'STAKING.SWITCH.OFF' | translate }}</span>

View file

@ -254,6 +254,14 @@
width: 2.5rem;
height: 2.5rem;
font-size: 1.2rem;
transition: all 0.3s;
}
.disabled {
background-color: #18202a;
color: #e0e0e0;
opacity: 0.3;
cursor: default;
transition: all 0.3s;
}
}
}

View file

@ -4,12 +4,15 @@ import { VariablesService } from '../_helpers/services/variables.service';
import { BackendService } from '../_helpers/services/backend.service';
import { TranslateService } from '@ngx-translate/core';
import { IntToMoneyPipe } from '../_helpers/pipes/int-to-money.pipe';
import { Subscription } from 'rxjs';
import {Subscription} from 'rxjs';
import { LOCKED_BALANCE_HELP_PAGE } from '../_shared/constants';
import icons from '../../assets/icons/icons.json';
import { PaginationService } from '../_helpers/services/pagination.service';
import { PaginationStore } from '../_helpers/services/pagination.store';
import {PaginationService} from '../_helpers/services/pagination.service';
import {PaginationStore} from '../_helpers/services/pagination.store';
import {Store, Sync} from 'store';
import {Wallet} from '../_helpers/models/wallet.model';
import {distinctUntilChanged, filter} from 'rxjs/operators';
@Component({
selector: 'app-wallet',
@ -25,9 +28,11 @@ export class WalletComponent implements OnInit, OnDestroy {
copyAnimationTimeout;
balanceTooltip;
activeTab = 'history';
public mining:boolean = false;
public mining = false;
public currentPage = 1;
wallet: Wallet;
sync_started = false;
stop_paginate = false;
@ViewChild('scrolledContent') private scrolledContent: ElementRef;
@ -88,6 +93,7 @@ export class WalletComponent implements OnInit, OnDestroy {
}
];
aliasSubscription: Subscription;
walletsSubscription: Subscription;
constructor(
private route: ActivatedRoute,
@ -98,21 +104,81 @@ export class WalletComponent implements OnInit, OnDestroy {
private translate: TranslateService,
private intToMoneyPipe: IntToMoneyPipe,
private pagination: PaginationService,
private paginationStore: PaginationStore
private paginationStore: PaginationStore,
private store: Store,
) { }
ngOnInit() {
this.subRouting1 = this.route.params.subscribe(params => {
// set current wallet only by user click to avoid after sync show synchronized data
this.walletID = +params['id'];
this.variablesService.setCurrentWallet(this.walletID);
this.walletsSubscription = this.store.select('sync').pipe(
filter(Boolean),
distinctUntilChanged(),
).subscribe(value => {
const data = value.filter((item: Sync) => item.wallet_id === this.walletID)[0];
if (data && !data.sync) {
let in_progress;
const values = this.store.value.sync;
if (values && values.length) {
in_progress = values.filter(item => item.sync);
this.variablesService.sync_started = !!(in_progress && in_progress.length);
if (!in_progress) {
this.variablesService.sync_started = false;
}
} else {
this.variablesService.sync_started = false;
}
}
let restore = false;
if (this.variablesService.after_sync_request.hasOwnProperty(this.walletID)) {
restore = this.variablesService.after_sync_request[this.walletID];
}
if (!this.variablesService.sync_started && restore && this.walletID === (data && data.wallet_id)) {
this.wallet = this.variablesService.getNotLoadedWallet();
if (this.wallet) {
this.tick();
}
// if this is was restore wallet and it was selected on moment when sync completed
this.getRecentTransfers();
this.variablesService.after_sync_request[this.walletID] = false;
}
});
let after_sync_request = false;
if (this.variablesService.after_sync_request.hasOwnProperty(this.walletID)) {
after_sync_request = this.variablesService.after_sync_request[this.walletID];
}
if (after_sync_request && !this.variablesService.sync_started) {
// if user click on the wallet at the first time after restore.
this.getRecentTransfers();
}
if (this.variablesService.stop_paginate.hasOwnProperty(this.walletID)) {
this.stop_paginate = this.variablesService.stop_paginate[this.walletID];
} else {
this.stop_paginate = false;
}
// this will hide pagination a bit earlier
this.wallet = this.variablesService.getNotLoadedWallet();
if (this.wallet) {
this.tick();
}
this.scrolledContent.nativeElement.scrollTop = 0;
clearTimeout(this.copyAnimationTimeout);
this.copyAnimation = false;
this.mining = this.variablesService.currentWallet.exclude_mining_txs;
if (this.variablesService.wallets.length === 1) {
this.walletID = +params['id'];
this.variablesService.setCurrentWallet(this.walletID);
}
});
this.subRouting2 = this.router.events.subscribe(val => {
if (val instanceof RoutesRecognized) {
this.activeTab = val.urlAfterRedirects.split('/').pop();
this.activeTab = val.urlAfterRedirects.replace('?sidenav=true', '').split('/').pop();
if (val.state.root.firstChild && val.state.root.firstChild.firstChild) {
for (let i = 0; i < this.tabs.length; i++) {
this.tabs[i].active = (this.tabs[i].link === '/' + val.state.root.firstChild.firstChild.url[0].path);
@ -138,6 +204,22 @@ export class WalletComponent implements OnInit, OnDestroy {
}
});
}
resetPaginationValues() {
this.ngZone.run(() => {
const total_history_item = this.variablesService.currentWallet.total_history_item;
const count = this.variablesService.count;
this.variablesService.currentWallet.totalPages = Math.ceil( total_history_item / count);
this.variablesService.currentWallet.exclude_mining_txs = this.mining;
this.variablesService.currentWallet.currentPage = 1;
if (!this.variablesService.currentWallet.totalPages) {
this.variablesService.currentWallet.totalPages = 1;
}
this.variablesService.currentWallet.totalPages > this.variablesService.maxPages
? this.variablesService.currentWallet.pages = new Array(5).fill(1).map((value, index) => value + index)
: this.variablesService.currentWallet.pages = new Array(this.variablesService.currentWallet.totalPages).fill(1).map((value, index) => value + index);
})
}
changeTab(index) {
if (((this.tabs[index].link === '/send' || this.tabs[index].link === '/contracts' || this.tabs[index].link === '/staking') && (this.variablesService.daemon_state !== 2 || !this.variablesService.currentWallet.loaded))
@ -195,59 +277,84 @@ export class WalletComponent implements OnInit, OnDestroy {
}
public setPage(pageNumber: number) {
// this is will allow pagination for wallets that was open from existed wallets'
if (this.variablesService.currentWallet.open_from_exist && !this.variablesService.currentWallet.updated) {
this.variablesService.get_recent_transfers = false;
this.variablesService.currentWallet.updated = true;
}
if (pageNumber === this.variablesService.currentWallet.currentPage) {
return;
}
this.variablesService.currentWallet.currentPage = pageNumber;
this.getRecentTransfers();
// if not running get_recent_transfers callback
if (!this.variablesService.get_recent_transfers) {
this.variablesService.currentWallet.currentPage = pageNumber;
}
if (!this.variablesService.get_recent_transfers) {
this.getRecentTransfers();
}
}
toggleMiningTransactions() {
this.mining = !this.mining;
const total_history_item = this.variablesService.currentWallet.total_history_item;
const count = this.variablesService.count;
this.variablesService.currentWallet.totalPages = Math.ceil( total_history_item / count);
this.variablesService.currentWallet.exclude_mining_txs = this.mining;
this.variablesService.currentWallet.currentPage = 1;
this.getRecentTransfers();
if (!this.variablesService.sync_started && !this.wallet) {
const value = this.paginationStore.value;
if (!value) {
this.paginationStore.setPage(1, 0, this.walletID); // add back page for the first page
} else {
const pages = value.filter(item => item.walletID === this.walletID);
if (!pages.length) {
this.paginationStore.setPage(1, 0, this.walletID); // add back page for the first page
}
}
this.mining = !this.mining;
this.resetPaginationValues();
this.getRecentTransfers();
}
}
tick() {
const walletInterval = setInterval(() => {
this.wallet = this.variablesService.getNotLoadedWallet();
if (!this.wallet) {
clearInterval(walletInterval);
}
}, 1000);
}
getRecentTransfers () {
const offset = this.pagination.getOffset();
const mining = this.variablesService.currentWallet.exclude_mining_txs;
const pages = this.paginationStore.value;
if (!pages && mining) {
this.paginationStore.setPage(1, 0); // add back page for the first page
}
const offset = this.pagination.getOffset(this.walletID);
const value = this.paginationStore.value;
const pages = value ? value.filter(item => item.walletID === this.walletID) : [];
this.backend.getRecentTransfers(
this.walletID,
offset,
this.variablesService.count, this.variablesService.currentWallet.exclude_mining_txs, (status, data) => {
const isForward = this.paginationStore.isForward(pages, this.variablesService.currentWallet.currentPage);
if (mining && isForward && pages && pages.length === 1) {
if (this.mining && isForward && pages && pages.length === 1) {
this.variablesService.currentWallet.currentPage = 1; // set init page after navigation back
}
const page = this.variablesService.currentWallet.currentPage + 1;
if (isForward && mining && data.history.length === this.variablesService.count) {
this.paginationStore.setPage(page, data.last_item_index); // add back page for current page
}
if (mining && data.history.length < this.variablesService.count) {
this.variablesService.currentWallet.totalPages = this.variablesService.currentWallet.currentPage; // stop paginate
}
if (status && data.total_history_items) {
this.variablesService.currentWallet.history.splice(0, this.variablesService.currentWallet.history.length);
this.ngZone.run(() => {
this.pagination.paginate(this.variablesService.currentWallet.currentPage);
if (data.history.length !== 0) {
this.variablesService.currentWallet.restore = false;
this.variablesService.currentWallet.total_history_item = data.total_history_items;
this.variablesService.currentWallet.prepareHistory(data.history);
if (this.variablesService.currentWallet.currentPage === 1 && data.unconfirmed) {
this.variablesService.currentWallet.prepareHistory(data.unconfirmed);
}
}
});
const history = (data && data.history);
this.variablesService.stop_paginate[this.walletID] = history && history.length < this.variablesService.count || !history;
this.stop_paginate = this.variablesService.stop_paginate[this.walletID];
if (!this.variablesService.stop_paginate[this.walletID]) {
const page = this.variablesService.currentWallet.currentPage + 1;
if (isForward && this.mining && history && history.length === this.variablesService.count) {
this.paginationStore.setPage(page, data.last_item_index, this.walletID); // add back page for current page
}
}
this.pagination.calcPages(data);
this.pagination.prepareHistory(data, status);
this.ngZone.run(() => {
this.variablesService.get_recent_transfers = false;
if (this.variablesService.after_sync_request.hasOwnProperty(this.walletID)) {
// this is will complete get_recent_transfers request
// this will switch of
this.variablesService.after_sync_request[this.walletID] = false;
}
});
});
}
@ -256,6 +363,9 @@ export class WalletComponent implements OnInit, OnDestroy {
this.subRouting2.unsubscribe();
this.queryRouting.unsubscribe();
this.aliasSubscription.unsubscribe();
if (this.walletsSubscription) {
this.walletsSubscription.unsubscribe();
}
clearTimeout(this.copyAnimationTimeout);
}

View file

@ -0,0 +1,36 @@
import { pluck, distinctUntilChanged } from 'rxjs/operators';
import { Observable, BehaviorSubject } from 'rxjs';
import { Wallet } from './app/_helpers/models/wallet.model';
export interface Sync {
sync: boolean;
wallet_id: number;
}
export interface State {
wallets: Wallet[];
sync: Sync[];
[key: string]: any;
}
const state: State = {
wallets: undefined,
sync: undefined,
};
export class Store {
private subject = new BehaviorSubject<State>(state);
private store = this.subject.asObservable().pipe(distinctUntilChanged());
get value() {
return this.subject.value;
}
select<T>(name: string): Observable<T> {
return this.store.pipe(pluck(name));
}
// tslint:disable-next-line:no-shadowed-variable
set(name: string, state: any) {
this.subject.next({ ...this.value, [name]: state });
}
}

View file

@ -2,6 +2,11 @@
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"paths": {
"store": [
"src/store.ts"
]
},
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,

View file

@ -53,6 +53,8 @@ namespace
const command_line::arg_descriptor<std::string> arg_pos_mining_reward_address = { "pos-mining-reward-address", "Block reward will be sent to the giving address if specified", "" };
const command_line::arg_descriptor<std::string> arg_restore_wallet = { "restore-wallet", "Restore wallet from seed phrase or tracking seed and save it to <arg>", "" };
const command_line::arg_descriptor<bool> arg_offline_mode = { "offline-mode", "Don't connect to daemon, work offline (for cold-signing process)", false, true };
const command_line::arg_descriptor<std::string> arg_scan_for_wallet = { "scan-for-wallet", "", "", true };
const command_line::arg_descriptor<std::string> arg_addr_to_compare = { "addr-to-compare", "", "", true };
const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""};
@ -1712,6 +1714,109 @@ bool simple_wallet::sweep_below(const std::vector<std::string> &args)
return true;
}
//----------------------------------------------------------------------------------------------------
uint64_t
get_tick_count__()
{
using namespace std::chrono;
return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
}
//----------------------------------------------------------------------------------------------------
bool check_if_file_looks_like_a_wallet(const std::wstring& wallet_)
{
std::string keys_buff;
boost::system::error_code e;
bool exists = boost::filesystem::exists(wallet_, e);
if (e || !exists)
return false;
boost::filesystem::ifstream data_file;
data_file.open(wallet_, std::ios_base::binary | std::ios_base::in);
if (data_file.fail())
return false;
tools::wallet_file_binary_header wbh = AUTO_VAL_INIT(wbh);
data_file.read((char*)&wbh, sizeof(wbh));
if (data_file.fail())
{
return false;
}
if (wbh.m_signature != WALLET_FILE_SIGNATURE_OLD && wbh.m_signature != WALLET_FILE_SIGNATURE_V2)
{
return false;
}
//std::cout << "\r \r";
LOG_PRINT_L0("Found wallet file: " << epee::string_encoding::convert_to_ansii(wallet_));
return false;
}
bool search_for_wallet_file(const std::wstring &search_here/*, const std::string &addr_to_compare*/)
{
if (search_here == L"/proc" || search_here == L"/bin" || search_here == L"/dev" || search_here == L"/etc"
|| search_here == L"/lib" || search_here == L"/lib64" || search_here == L"/proc" || search_here == L"/run"
|| search_here == L"/sbin" || search_here == L"/srv" || search_here == L"/sys" || search_here == L"/usr"
|| search_here == L"/var")
{
LOG_PRINT_L0("Skiping " << epee::string_encoding::convert_to_ansii(search_here));
return false;
}
//LOG_PRINT_L0("FOLDER: " << epee::string_encoding::convert_to_ansii(search_here));
static uint64_t last_tick = 0;
using namespace boost::filesystem;
//recursive_directory_iterator dir(search_here), end;
try
{
for (auto& dir : boost::make_iterator_range(directory_iterator(search_here), {}))
{
boost::system::error_code ec = AUTO_VAL_INIT(ec);
bool r = boost::filesystem::is_directory(dir.path(), ec);
if (r)
{
if (get_tick_count__() - last_tick > 300)
{
last_tick = get_tick_count__();
//std::cout << "\r \r ->" << dir.path();
}
bool r = search_for_wallet_file(dir.path().wstring());
if (r)
return true;
}
else
{
boost::system::error_code ec = AUTO_VAL_INIT(ec);
bool r = boost::filesystem::is_regular_file(dir.path(), ec);
if (!r)
{
//LOG_PRINT_L0("Skiping as not regular: " << epee::string_encoding::convert_to_ansii(dir.path().wstring()));
return false;
}
//LOG_PRINT_L0("FILE: " << dir.path().string());
std::wstring pa = dir.path().wstring();
r = check_if_file_looks_like_a_wallet(pa);
if (r)
return true;
}
}
}
catch (std::exception& /* ex*/)
{
//std::cout << "\r \r";
LOG_PRINT_CYAN("Skip: " << search_here, LOG_LEVEL_0);
return false;
}
return false;
}
//----------------------------------------------------------------------------------------------------
#ifdef WIN32
int wmain( int argc, wchar_t* argv_w[ ], wchar_t* envp[ ] )
@ -1770,7 +1875,8 @@ int main(int argc, char* argv[])
command_line::add_arg(desc_params, arg_offline_mode);
command_line::add_arg(desc_params, command_line::arg_log_file);
command_line::add_arg(desc_params, command_line::arg_log_level);
command_line::add_arg(desc_params, arg_scan_for_wallet);
command_line::add_arg(desc_params, arg_addr_to_compare);
tools::wallet_rpc_server::init_options(desc_params);
@ -1827,6 +1933,17 @@ int main(int argc, char* argv[])
log_space::get_set_log_detalisation_level(true, command_line::get_arg(vm, command_line::arg_log_level));
}
if (command_line::has_arg(vm, arg_scan_for_wallet))
{
log_space::log_singletone::add_logger(LOGGER_CONSOLE, nullptr, nullptr, LOG_LEVEL_4);
LOG_PRINT_L0("Searching from "
<< epee::string_encoding::convert_to_ansii(command_line::get_arg(vm, arg_scan_for_wallet)));
search_for_wallet_file(epee::string_encoding::convert_to_unicode(command_line::get_arg(vm, arg_scan_for_wallet)));
return EXIT_SUCCESS;
}
bool offline_mode = command_line::get_arg(vm, arg_offline_mode);
if (command_line::has_arg(vm, tools::wallet_rpc_server::arg_rpc_bind_port))

View file

@ -8,6 +8,6 @@
#define PROJECT_REVISION "7"
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
#define PROJECT_VERSION_BUILD_NO 109
#define PROJECT_VERSION_BUILD_NO 110
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"