diff --git a/src/app/shared/components/currency-unit-converter/currency-unit-converter.component.ts b/src/app/shared/components/currency-unit-converter/currency-unit-converter.component.ts index 4dc4a9bb..eb39b5a2 100644 --- a/src/app/shared/components/currency-unit-converter/currency-unit-converter.component.ts +++ b/src/app/shared/components/currency-unit-converter/currency-unit-converter.component.ts @@ -1,5 +1,5 @@ import { Component, Input, OnInit, OnChanges, OnDestroy } from '@angular/core'; -import { Subject } from 'rxjs'; +import { Subject, forkJoin } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { Store } from '@ngrx/store'; @@ -28,7 +28,7 @@ export class CurrencyUnitConverterComponent implements OnInit, OnChanges, OnDest ngOnChanges() { if (this.currencyUnits.length > 1 && this.values[0] && this.values[0].dataValue >= 0) { - this.getCurrencyValues(this.values); + this.getCurrencyValues(); } } @@ -40,32 +40,33 @@ export class CurrencyUnitConverterComponent implements OnInit, OnChanges, OnDest this.currencyUnits.splice(2, 1); } if (this.currencyUnits.length > 1 && this.values[0] && this.values[0].dataValue >= 0) { - this.getCurrencyValues(this.values); + this.getCurrencyValues(); } }); } - getCurrencyValues(values) { - values.forEach((value) => { + getCurrencyValues() { + this.values.forEach((value, i) => { if (value.dataValue > 0) { - this.commonService.convertCurrency(value.dataValue, CurrencyUnitEnum.SATS, CurrencyUnitEnum.BTC, '', true). + this.commonService.convertCurrency(value.dataValue, CurrencyUnitEnum.SATS, CurrencyUnitEnum.BTC, '', true, value.title). pipe(takeUntil(this.unSubs[1])). subscribe((data) => { - value[CurrencyUnitEnum.BTC] = data.BTC; + this.values[i][CurrencyUnitEnum.BTC] = data.BTC; }); - this.commonService.convertCurrency(value.dataValue, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, this.currencyUnits[2], this.fiatConversion). + this.commonService.convertCurrency(value.dataValue, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, this.currencyUnits[2], this.fiatConversion, value.title). pipe(takeUntil(this.unSubs[2])). subscribe({ next: (data) => { - value[CurrencyUnitEnum.OTHER] = data.OTHER; + console.log(data); + this.values[i][CurrencyUnitEnum.OTHER] = data.OTHER; }, error: (err) => { this.conversionErrorMsg = 'Conversion Error: ' + err; } }); } else { - value[CurrencyUnitEnum.BTC] = value.dataValue; + this.values[i][CurrencyUnitEnum.BTC] = value.dataValue; if (this.conversionErrorMsg === '') { - value[CurrencyUnitEnum.OTHER] = value.dataValue; + this.values[i][CurrencyUnitEnum.OTHER] = value.dataValue; } } }); diff --git a/src/app/shared/components/node-config/node-settings/node-settings.component.ts b/src/app/shared/components/node-config/node-settings/node-settings.component.ts index 87327ff4..1fd67112 100644 --- a/src/app/shared/components/node-config/node-settings/node-settings.component.ts +++ b/src/app/shared/components/node-config/node-settings/node-settings.component.ts @@ -9,8 +9,8 @@ import { Node, Settings } from '../../../models/RTLconfig'; import { LoggerService } from '../../../services/logger.service'; import { CommonService } from '../../../services/common.service'; import { RTLState } from '../../../../store/rtl.state'; -import { updateNodeSettings, setSelectedNode } from '../../../../store/rtl.actions'; import { rootSelectedNode } from '../../../../store/rtl.selector'; +import { updateNodeSettings, setSelectedNode, updateSelectedNodeSettings } from '../../../../store/rtl.actions'; import { setChildNodeSettingsLND } from '../../../../lnd/store/lnd.actions'; import { setChildNodeSettingsCLN } from '../../../../cln/store/cln.actions'; import { setChildNodeSettingsECL } from '../../../../eclair/store/ecl.actions'; @@ -61,9 +61,11 @@ export class NodeSettingsComponent implements OnInit, OnDestroy { onCurrencyChange(event: any) { this.selNode.settings.currencyUnits = [...CURRENCY_UNITS, event.value]; + this.store.dispatch(updateSelectedNodeSettings({ payload: this.selNode })); this.store.dispatch(setChildNodeSettingsLND({ payload: this.selNode })); this.store.dispatch(setChildNodeSettingsCLN({ payload: this.selNode })); this.store.dispatch(setChildNodeSettingsECL({ payload: this.selNode })); + // this.store.dispatch(updateNodeSettings({ payload: this.selNode })); } toggleSettings(toggleField: string, event?: any) { @@ -84,9 +86,7 @@ export class NodeSettingsComponent implements OnInit, OnDestroy { return true; } this.logger.info(this.selNode.settings); - this.store.dispatch(setChildNodeSettingsLND({ payload: this.selNode })); - this.store.dispatch(setChildNodeSettingsCLN({ payload: this.selNode })); - this.store.dispatch(setChildNodeSettingsECL({ payload: this.selNode })); + this.store.dispatch(updateNodeSettings({ payload: this.selNode })); } onResetSettings() { diff --git a/src/app/shared/models/rtlModels.ts b/src/app/shared/models/rtlModels.ts index f62d2a06..f9b9ad7a 100644 --- a/src/app/shared/models/rtlModels.ts +++ b/src/app/shared/models/rtlModels.ts @@ -15,9 +15,7 @@ export interface SetSelectedNode { } export interface UpdateNodeSettings { - uiMessage: string; - defaultNodeIndex?: number; - service: ServicesEnum; + index: number; settings: Settings; } diff --git a/src/app/shared/services/common.service.ts b/src/app/shared/services/common.service.ts index 9c627887..891f8994 100644 --- a/src/app/shared/services/common.service.ts +++ b/src/app/shared/services/common.service.ts @@ -1,7 +1,7 @@ import { Injectable, OnDestroy } from '@angular/core'; import { DatePipe } from '@angular/common'; -import { of, Observable, throwError, BehaviorSubject } from 'rxjs'; -import { take, map, catchError } from 'rxjs/operators'; +import { Subject, of, Observable, throwError, BehaviorSubject } from 'rxjs'; +import { catchError, switchMap, takeUntil } from 'rxjs/operators'; import { LoggerService } from './logger.service'; import { DataService } from './data.service'; @@ -17,6 +17,7 @@ export class CommonService implements OnDestroy { private screenSize = ScreenSizeEnum.MD; private containerSize = { width: 0, height: 0 }; public containerSizeUpdated: BehaviorSubject = new BehaviorSubject(this.containerSize); + private unSubs = [new Subject(), new Subject(), new Subject()]; constructor(public dataService: DataService, private logger: LoggerService, private datePipe: DatePipe) { } @@ -89,25 +90,43 @@ export class CommonService implements OnDestroy { } } - convertCurrency(value: number, from: string, to: string, otherCurrencyUnit: string, fiatConversion: boolean): Observable { + convertCurrency(value: number, from: string, to: string, otherCurrencyUnit: string, fiatConversion: boolean, title?: string): Observable { const latest_date = new Date().valueOf(); - if (fiatConversion && otherCurrencyUnit && this.ratesAPIStatus !== APICallStatusEnum.INITIATED && (from === CurrencyUnitEnum.OTHER || to === CurrencyUnitEnum.OTHER)) { - if (this.conversionData.data && this.conversionData.last_fetched && (latest_date < (this.conversionData.last_fetched + 300000))) { + console.warn(value, from, to, otherCurrencyUnit, fiatConversion, title, this.conversionData.data); + if (fiatConversion && otherCurrencyUnit && (from === CurrencyUnitEnum.OTHER || to === CurrencyUnitEnum.OTHER)) { + console.warn('1'); + if (this.ratesAPIStatus !== APICallStatusEnum.INITIATED) { + console.warn('2'); + if (this.conversionData.data && this.conversionData.last_fetched && (latest_date < (this.conversionData.last_fetched + 300000))) { + console.warn('3'); + return of(this.convertWithFiat(value, from, otherCurrencyUnit)); + } else { + console.warn('4'); + this.ratesAPIStatus = APICallStatusEnum.INITIATED; + return this.dataService.getFiatRates().pipe(takeUntil(this.unSubs[0]), + switchMap((data) => { + console.warn('5'); + this.ratesAPIStatus = APICallStatusEnum.COMPLETED; + this.conversionData.data = (data && typeof data === 'object') ? data : (data && typeof data === 'string') ? JSON.parse(data) : {}; + this.conversionData.last_fetched = latest_date; + return of(this.convertWithFiat(value, from, otherCurrencyUnit)); + }), + catchError((err) => { + this.ratesAPIStatus = APICallStatusEnum.ERROR; + return throwError(() => this.extractErrorMessage(err, 'Currency Conversion Error.')); + }) + ); + } + } else if (this.conversionData.data && this.conversionData.last_fetched && (latest_date < (this.conversionData.last_fetched + 300000))) { + console.warn('6'); return of(this.convertWithFiat(value, from, otherCurrencyUnit)); } else { - this.ratesAPIStatus = APICallStatusEnum.INITIATED; - return this.dataService.getFiatRates().pipe(take(1), - map((data: any) => { - this.ratesAPIStatus = APICallStatusEnum.COMPLETED; - this.conversionData.data = (data && typeof data === 'object') ? data : (data && typeof data === 'string') ? JSON.parse(data) : {}; - this.conversionData.last_fetched = latest_date; - return this.convertWithFiat(value, from, otherCurrencyUnit); - }), - catchError((err) => { - this.ratesAPIStatus = APICallStatusEnum.ERROR; - return throwError(() => this.extractErrorMessage(err, 'Currency Conversion Error.')); - }) - ); + console.warn(this.conversionData.data); + console.warn(this.conversionData.last_fetched); + console.warn(latest_date < (this.conversionData.last_fetched + 300000)); + console.warn(this.conversionData.data && this.conversionData.last_fetched && (latest_date < (this.conversionData.last_fetched + 300000))); + console.warn('7'); + return of(this.convertWithoutFiat(value, from)); } } else { return of(this.convertWithoutFiat(value, from)); diff --git a/src/app/shared/services/consts-enums-functions.ts b/src/app/shared/services/consts-enums-functions.ts index 419a5658..6934b710 100644 --- a/src/app/shared/services/consts-enums-functions.ts +++ b/src/app/shared/services/consts-enums-functions.ts @@ -426,6 +426,7 @@ export enum RTLActions { UPDATE_ROOT_NODE_SETTINGS = 'UPDATE_ROOT_NODE_SETTINGS', UPDATE_APPLICATION_SETTINGS = 'UPDATE_APPLICATION_SETTINGS', UPDATE_NODE_SETTINGS = 'UPDATE_NODE_SETTINGS', + UPDATE_SELECTED_NODE_SETTINGS = 'UPDATE_SELECTED_NODE_SETTINGS', SET_NODE_DATA = 'SET_NODE_DATA', IS_AUTHORIZED = 'IS_AUTHORIZED', IS_AUTHORIZED_RES = 'IS_AUTHORIZED_RES', diff --git a/src/app/store/rtl.actions.ts b/src/app/store/rtl.actions.ts index d9209f84..bf8b78ac 100644 --- a/src/app/store/rtl.actions.ts +++ b/src/app/store/rtl.actions.ts @@ -3,7 +3,7 @@ import { createAction, props } from '@ngrx/store'; import { DialogConfig } from '../shared/models/alertData'; import { ApiCallStatusPayload } from '../shared/models/apiCallsPayload'; import { RTLConfiguration, Node, GetInfoRoot } from '../shared/models/RTLconfig'; -import { FetchFile, Login, OpenSnackBar, ResetPassword, SetSelectedNode, UpdateNodeSettings, VerifyTwoFA } from '../shared/models/rtlModels'; +import { FetchFile, Login, OpenSnackBar, ResetPassword, SetSelectedNode, VerifyTwoFA } from '../shared/models/rtlModels'; import { RTLActions } from '../shared/services/consts-enums-functions'; export const voidAction = createAction(RTLActions.VOID); @@ -44,7 +44,9 @@ export const setApplicationSettings = createAction(RTLActions.SET_APPLICATION_SE export const setSelectedNode = createAction(RTLActions.SET_SELECTED_NODE, props<{ payload: SetSelectedNode }>()); -export const updateNodeSettings = createAction(RTLActions.UPDATE_NODE_SETTINGS, props<{ payload: UpdateNodeSettings }>()); +export const updateNodeSettings = createAction(RTLActions.UPDATE_NODE_SETTINGS, props<{ payload: Node }>()); + +export const updateSelectedNodeSettings = createAction(RTLActions.UPDATE_SELECTED_NODE_SETTINGS, props<{ payload: Node }>()); export const updateApplicationSettings = createAction(RTLActions.UPDATE_APPLICATION_SETTINGS, props<{ payload: { showSnackBar: boolean, message: string, config: RTLConfiguration } }>()); diff --git a/src/app/store/rtl.effects.ts b/src/app/store/rtl.effects.ts index 1de06964..cf2f6418 100644 --- a/src/app/store/rtl.effects.ts +++ b/src/app/store/rtl.effects.ts @@ -17,7 +17,7 @@ import { DataService } from '../shared/services/data.service'; import { RTLConfiguration, Node, GetInfoRoot } from '../shared/models/RTLconfig'; import { API_URL, API_END_POINTS, RTLActions, APICallStatusEnum, AuthenticateWith, CURRENCY_UNITS, ScreenSizeEnum, UI_MESSAGES } from '../shared/services/consts-enums-functions'; import { DialogConfig } from '../shared/models/alertData'; -import { FetchFile, Login, OpenSnackBar, ResetPassword, UpdateNodeSettings, SetSelectedNode, VerifyTwoFA } from '../shared/models/rtlModels'; +import { FetchFile, Login, OpenSnackBar, ResetPassword, SetSelectedNode, VerifyTwoFA } from '../shared/models/rtlModels'; import { SpinnerDialogComponent } from '../shared/components/data-modal/spinner-dialog/spinner-dialog.component'; import { AlertMessageComponent } from '../shared/components/data-modal/alert-message/alert-message.component'; @@ -26,10 +26,10 @@ import { ErrorMessageComponent } from '../shared/components/data-modal/error-mes import { ShowPubkeyComponent } from '../shared/components/data-modal/show-pubkey/show-pubkey.component'; import { RTLState } from './rtl.state'; -import { resetRootStore, setNodeData, setSelectedNode, updateRootAPICallStatus, closeSpinner, openAlert, openSpinner, openSnackBar, fetchRTLConfig, closeAllDialogs, logout } from './rtl.actions'; -import { fetchInfoLND, resetLNDStore, fetchPageSettings as fetchPageSettingsLND } from '../lnd/store/lnd.actions'; -import { fetchInfoCLN, resetCLNStore, fetchPageSettings as fetchPageSettingsCLN } from '../cln/store/cln.actions'; -import { fetchInfoECL, resetECLStore, fetchPageSettings as fetchPageSettingsECL } from '../eclair/store/ecl.actions'; +import { resetRootStore, setNodeData, setSelectedNode, updateRootAPICallStatus, closeSpinner, openAlert, openSpinner, openSnackBar, fetchRTLConfig, closeAllDialogs, logout, updateSelectedNodeSettings } from './rtl.actions'; +import { fetchInfoLND, resetLNDStore, fetchPageSettings as fetchPageSettingsLND, setChildNodeSettingsLND } from '../lnd/store/lnd.actions'; +import { fetchInfoCLN, resetCLNStore, fetchPageSettings as fetchPageSettingsCLN, setChildNodeSettingsCLN } from '../cln/store/cln.actions'; +import { fetchInfoECL, resetECLStore, fetchPageSettings as fetchPageSettingsECL, setChildNodeSettingsECL } from '../eclair/store/ecl.actions'; import { rootAppConfig, rootNodeData } from './rtl.selector'; @Injectable() @@ -246,19 +246,23 @@ export class RTLEffects implements OnDestroy { updateNodeSettings = createEffect( () => this.actions.pipe( ofType(RTLActions.UPDATE_NODE_SETTINGS), - mergeMap((action: { type: string, payload: UpdateNodeSettings }) => { - this.store.dispatch(openSpinner({ payload: UI_MESSAGES.UPDATE_APPLICATION_SETTINGS })); + mergeMap((action: { type: string, payload: Node }) => { + this.store.dispatch(openSpinner({ payload: UI_MESSAGES.UPDATE_NODE_SETTINGS })); this.store.dispatch(updateRootAPICallStatus({ payload: { action: 'updateNodeSettings', status: APICallStatusEnum.INITIATED } })); return this.httpClient.post(API_END_POINTS.CONF_API + '/node', action.payload). - pipe(map((updatedNode: UpdateNodeSettings) => { + pipe(map((updatedNode: Node) => { this.store.dispatch(updateRootAPICallStatus({ payload: { action: 'updateNodeSettings', status: APICallStatusEnum.COMPLETED } })); - this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.UPDATE_APPLICATION_SETTINGS })); + this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.UPDATE_NODE_SETTINGS })); + this.store.dispatch(updateSelectedNodeSettings({ payload: updatedNode })); + this.store.dispatch(setChildNodeSettingsLND({ payload: action.payload })); + this.store.dispatch(setChildNodeSettingsCLN({ payload: action.payload })); + this.store.dispatch(setChildNodeSettingsECL({ payload: action.payload })); return { type: RTLActions.OPEN_SNACK_BAR, payload: 'Node settings updated successfully!' }; }), catchError((err: any) => { - this.handleErrorWithAlert('updateNodeSettings', UI_MESSAGES.UPDATE_APPLICATION_SETTINGS, 'Update Node Settings Failed!', API_END_POINTS.CONF_API + '/node', err); + this.handleErrorWithAlert('updateNodeSettings', UI_MESSAGES.UPDATE_NODE_SETTINGS, 'Update Node Settings Failed!', API_END_POINTS.CONF_API + '/node', err); return of({ type: RTLActions.VOID }); })); })) diff --git a/src/app/store/rtl.reducers.ts b/src/app/store/rtl.reducers.ts index ec6bec2f..76d23cdf 100644 --- a/src/app/store/rtl.reducers.ts +++ b/src/app/store/rtl.reducers.ts @@ -1,7 +1,7 @@ import { createReducer, on } from '@ngrx/store'; import { initRootState } from './rtl.state'; -import { resetRootStore, setNodeData, setApplicationSettings, setSelectedNode, updateRootAPICallStatus } from './rtl.actions'; +import { resetRootStore, setNodeData, setApplicationSettings, updateSelectedNodeSettings, updateRootAPICallStatus } from './rtl.actions'; export const RootReducer = createReducer(initRootState, on(updateRootAPICallStatus, (state, { payload }) => { @@ -26,9 +26,9 @@ export const RootReducer = createReducer(initRootState, appConfig: state.appConfig, selNode: payload })), - on(setSelectedNode, (state, { payload }) => ({ + on(updateSelectedNodeSettings, (state, { payload }) => ({ ...state, - selNode: payload.currentLnNode + selNode: payload })), on(setNodeData, (state, { payload }) => ({ ...state,