2023-06-17 21:04:23 +02:00
|
|
|
import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
|
|
|
|
import { FormBuilder, FormGroup } from '@angular/forms';
|
|
|
|
import { combineLatest, Observable } from 'rxjs';
|
|
|
|
import { map, switchMap } from 'rxjs/operators';
|
|
|
|
import { StateService } from '../../services/state.service';
|
|
|
|
import { WebsocketService } from '../../services/websocket.service';
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-calculator',
|
|
|
|
templateUrl: './calculator.component.html',
|
|
|
|
styleUrls: ['./calculator.component.scss'],
|
|
|
|
changeDetection: ChangeDetectionStrategy.OnPush
|
|
|
|
})
|
|
|
|
export class CalculatorComponent implements OnInit {
|
|
|
|
satoshis = 10000;
|
|
|
|
form: FormGroup;
|
|
|
|
|
|
|
|
currency$ = this.stateService.fiatCurrency$;
|
|
|
|
price$: Observable<number>;
|
2023-06-18 00:16:47 +02:00
|
|
|
lastFiatPrice$: Observable<number>;
|
2023-06-17 21:04:23 +02:00
|
|
|
|
|
|
|
constructor(
|
|
|
|
private stateService: StateService,
|
|
|
|
private formBuilder: FormBuilder,
|
|
|
|
private websocketService: WebsocketService,
|
|
|
|
) { }
|
|
|
|
|
|
|
|
ngOnInit(): void {
|
|
|
|
this.form = this.formBuilder.group({
|
|
|
|
fiat: [0],
|
|
|
|
bitcoin: [0],
|
|
|
|
satoshis: [0],
|
|
|
|
});
|
|
|
|
|
2023-06-18 00:16:47 +02:00
|
|
|
this.lastFiatPrice$ = this.stateService.conversions$.asObservable()
|
|
|
|
.pipe(
|
|
|
|
map((conversions) => conversions.time)
|
|
|
|
);
|
|
|
|
|
|
|
|
let currency;
|
2023-06-17 21:04:23 +02:00
|
|
|
this.price$ = this.currency$.pipe(
|
2023-06-18 00:16:47 +02:00
|
|
|
switchMap((result) => {
|
|
|
|
currency = result;
|
2023-06-17 21:04:23 +02:00
|
|
|
return this.stateService.conversions$.asObservable();
|
|
|
|
}),
|
|
|
|
map((conversions) => {
|
2023-06-18 00:16:47 +02:00
|
|
|
return conversions[currency];
|
2023-06-17 21:04:23 +02:00
|
|
|
})
|
|
|
|
);
|
|
|
|
|
|
|
|
combineLatest([
|
|
|
|
this.price$,
|
|
|
|
this.form.get('fiat').valueChanges
|
|
|
|
]).subscribe(([price, value]) => {
|
|
|
|
const rate = (value / price).toFixed(8);
|
|
|
|
const satsRate = Math.round(value / price * 100_000_000);
|
2023-07-15 15:09:41 +09:00
|
|
|
if (isNaN(value)) {
|
|
|
|
return;
|
|
|
|
}
|
2023-06-17 21:04:23 +02:00
|
|
|
this.form.get('bitcoin').setValue(rate, { emitEvent: false });
|
|
|
|
this.form.get('satoshis').setValue(satsRate, { emitEvent: false } );
|
|
|
|
});
|
|
|
|
|
|
|
|
combineLatest([
|
|
|
|
this.price$,
|
|
|
|
this.form.get('bitcoin').valueChanges
|
|
|
|
]).subscribe(([price, value]) => {
|
|
|
|
const rate = parseFloat((value * price).toFixed(8));
|
2023-07-15 15:09:41 +09:00
|
|
|
if (isNaN(value)) {
|
|
|
|
return;
|
|
|
|
}
|
2023-06-17 21:04:23 +02:00
|
|
|
this.form.get('fiat').setValue(rate, { emitEvent: false } );
|
|
|
|
this.form.get('satoshis').setValue(Math.round(value * 100_000_000), { emitEvent: false } );
|
|
|
|
});
|
|
|
|
|
|
|
|
combineLatest([
|
|
|
|
this.price$,
|
|
|
|
this.form.get('satoshis').valueChanges
|
|
|
|
]).subscribe(([price, value]) => {
|
|
|
|
const rate = parseFloat((value / 100_000_000 * price).toFixed(8));
|
|
|
|
const bitcoinRate = (value / 100_000_000).toFixed(8);
|
2023-07-15 15:09:41 +09:00
|
|
|
if (isNaN(value)) {
|
|
|
|
return;
|
|
|
|
}
|
2023-06-17 21:04:23 +02:00
|
|
|
this.form.get('fiat').setValue(rate, { emitEvent: false } );
|
|
|
|
this.form.get('bitcoin').setValue(bitcoinRate, { emitEvent: false });
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-06-18 00:16:47 +02:00
|
|
|
transformInput(name: string): void {
|
|
|
|
const formControl = this.form.get(name);
|
|
|
|
if (!formControl.value) {
|
|
|
|
return formControl.setValue('', {emitEvent: false});
|
|
|
|
}
|
|
|
|
let value = formControl.value.replace(',', '.').replace(/[^0-9.]/g, '');
|
|
|
|
if (value === '.') {
|
|
|
|
value = '0';
|
|
|
|
}
|
2023-07-15 15:09:41 +09:00
|
|
|
let sanitizedValue = this.removeExtraDots(value);
|
|
|
|
if (name === 'bitcoin' && this.countDecimals(sanitizedValue) > 8) {
|
|
|
|
sanitizedValue = this.toFixedWithoutRounding(sanitizedValue, 8);
|
|
|
|
}
|
|
|
|
if (sanitizedValue === '') {
|
|
|
|
sanitizedValue = '0';
|
|
|
|
}
|
|
|
|
if (name === 'satoshis') {
|
|
|
|
sanitizedValue = parseFloat(sanitizedValue).toFixed(0);
|
|
|
|
}
|
2023-06-18 00:16:47 +02:00
|
|
|
formControl.setValue(sanitizedValue, {emitEvent: true});
|
|
|
|
}
|
|
|
|
|
|
|
|
removeExtraDots(str: string): string {
|
|
|
|
const [beforeDot, afterDot] = str.split('.', 2);
|
|
|
|
if (afterDot === undefined) {
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
const afterDotReplaced = afterDot.replace(/\./g, '');
|
|
|
|
return `${beforeDot}.${afterDotReplaced}`;
|
|
|
|
}
|
2023-07-15 15:09:41 +09:00
|
|
|
|
|
|
|
countDecimals(numberString: string): number {
|
|
|
|
const decimalPos = numberString.indexOf('.');
|
|
|
|
if (decimalPos === -1) return 0;
|
|
|
|
return numberString.length - decimalPos - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
toFixedWithoutRounding(numStr: string, fixed: number): string {
|
|
|
|
const re = new RegExp(`^-?\\d+(?:.\\d{0,${(fixed || -1)}})?`);
|
|
|
|
const result = numStr.match(re);
|
|
|
|
return result ? result[0] : numStr;
|
|
|
|
}
|
2023-06-17 21:04:23 +02:00
|
|
|
}
|