Skip to content

Commit

Permalink
Merge pull request #2526 from kaloudis/btc-amt-formatting
Browse files Browse the repository at this point in the history
BTC amount formatting: Decimals: remove commas and add spaces
  • Loading branch information
kaloudis authored Nov 15, 2024
2 parents 412fc20 + 883a8fa commit ec5b99a
Show file tree
Hide file tree
Showing 24 changed files with 282 additions and 114 deletions.
17 changes: 13 additions & 4 deletions components/Amount.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import * as React from 'react';
import { TouchableOpacity, StyleSheet, View } from 'react-native';
import { inject, observer } from 'mobx-react';

import FiatStore from '../stores/FiatStore';
import UnitsStore from '../stores/UnitsStore';
import SettingsStore from '../stores/SettingsStore';
import PrivacyUtils from '../utils/PrivacyUtils';
import ClockIcon from '../assets/images/SVG/Clock.svg';
import { localeString } from '../utils/LocaleUtils';
import { themeColor } from '../utils/ThemeUtils';

import { Spacer } from './layout/Spacer';
import { Row } from './layout/Row';
import { Body } from './text/Body';
import LoadingIndicator from './LoadingIndicator';

import { localeString } from '../utils/LocaleUtils';
import { themeColor } from '../utils/ThemeUtils';
import { formatBitcoinWithSpaces } from '../utils/UnitsUtils';
import PrivacyUtils from '../utils/PrivacyUtils';

import ClockIcon from '../assets/images/SVG/Clock.svg';

import stores from '../stores/Stores';

type Units = 'sats' | 'BTC' | 'fiat';
Expand Down Expand Up @@ -185,6 +190,8 @@ function AmountDisplay({
{negative ? '-' : ''}
{amount === 'N/A' && fiatRatesLoading ? (
<LoadingIndicator size={20} />
) : unit === 'BTC' ? (
formatBitcoinWithSpaces(amount)
) : (
amount.toString()
)}
Expand Down Expand Up @@ -216,6 +223,8 @@ function AmountDisplay({
{negative ? '-' : ''}
{amount === 'N/A' && fiatRatesLoading ? (
<LoadingIndicator size={20} />
) : unit === 'BTC' ? (
formatBitcoinWithSpaces(amount)
) : (
amount.toString()
)}
Expand Down
3 changes: 2 additions & 1 deletion components/AmountInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import Amount from './Amount';
import TextInput from './TextInput';

import { themeColor } from '../utils/ThemeUtils';
import { SATS_PER_BTC } from '../utils/UnitsUtils';

import Stores from '../stores/Stores';
import FiatStore from '../stores/FiatStore';
import SettingsStore from '../stores/SettingsStore';
import UnitsStore, { SATS_PER_BTC } from '../stores/UnitsStore';
import UnitsStore from '../stores/UnitsStore';

import ExchangeBitcoinSVG from '../assets/images/SVG/ExchangeBitcoin.svg';
import ExchangeFiatSVG from '../assets/images/SVG/ExchangeFiat.svg';
Expand Down
8 changes: 3 additions & 5 deletions components/LSPS1OrderResponse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,22 @@ import Button from './Button';

import { localeString } from '../utils/LocaleUtils';
import { themeColor } from '../utils/ThemeUtils';
import { numberWithCommas } from '../utils/UnitsUtils';
import UrlUtils from '../utils/UrlUtils';

import InvoicesStore from '../stores/InvoicesStore';
import NodeInfoStore from '../stores/NodeInfoStore';
import FiatStore from '../stores/FiatStore';
import { ChannelItem } from './Channels/ChannelItem';

interface LSPS1OrderResponseProps {
navigation: any;
orderResponse: any;
InvoicesStore?: InvoicesStore;
NodeInfoStore?: NodeInfoStore;
FiatStore?: FiatStore;
orderView: boolean;
}

@inject('InvoicesStore', 'NodeInfoStore', 'FiatStore')
@inject('InvoicesStore', 'NodeInfoStore')
@observer
export default class LSPS1OrderResponse extends React.Component<
LSPS1OrderResponseProps,
Expand All @@ -38,7 +37,6 @@ export default class LSPS1OrderResponse extends React.Component<
orderResponse,
InvoicesStore,
NodeInfoStore,
FiatStore,
orderView,
navigation
} = this.props;
Expand Down Expand Up @@ -108,7 +106,7 @@ export default class LSPS1OrderResponse extends React.Component<
keyValue={localeString(
'views.LSPS1.channelExpiryBlocks'
)}
value={FiatStore!.numberWithCommas(
value={numberWithCommas(
orderResponse?.channel_expiry_blocks
)}
/>
Expand Down
1 change: 1 addition & 0 deletions locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,7 @@
"views.Settings.Display.displayNickname": "Display node nickname on main views",
"views.Settings.Display.bigKeypadButtons": "Big keypad buttons",
"views.Settings.Display.showAllDecimalPlaces": "Show all decimal places",
"views.Settings.Display.removeDecimalSpaces": "Remove decimal spaces from Bitcoin denominated amounts",
"views.Settings.Display.showMillisatoshiAmounts": "Show millisatoshi amounts",
"views.Settings.Display.selectNodeOnStartup": "Select node on startup",
"views.Settings.privacy": "Privacy",
Expand Down
25 changes: 11 additions & 14 deletions stores/FiatStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import ReactNativeBlobUtil from 'react-native-blob-util';
import BigNumber from 'bignumber.js';

import SettingsStore from './SettingsStore';
import { SATS_PER_BTC } from './UnitsStore';
import {
SATS_PER_BTC,
numberWithCommas,
numberWithDecimals
} from '../utils/UnitsUtils';

interface CurrencyDisplayRules {
symbol: string;
Expand All @@ -24,13 +28,6 @@ export default class FiatStore {
@observable public loading = false;
@observable public error = false;

@observable public numberWithCommas = (x: string | number) =>
x?.toString()?.replace(/\B(?=(\d{3})+(?!\d))/g, ',') || '0';

@observable public numberWithDecimals = (x: string | number) =>
this.numberWithCommas(x).replace(/[,.]/g, (y: string) =>
y === ',' ? '.' : ','
);
private sourceOfCurrentFiatRates: string | undefined;

getFiatRatesToken: any;
Expand Down Expand Up @@ -581,12 +578,12 @@ export default class FiatStore {
.toFixed(0);

const formattedRate = separatorSwap
? this.numberWithDecimals(rate)
: this.numberWithCommas(rate);
? numberWithDecimals(rate)
: numberWithCommas(rate);

const formattedMoscow = separatorSwap
? this.numberWithDecimals(moscowTime)
: this.numberWithCommas(moscowTime);
? numberWithDecimals(moscowTime)
: numberWithCommas(moscowTime);

if (sats) {
return `${formattedMoscow} sats = 1 ${fiat}`;
Expand Down Expand Up @@ -749,8 +746,8 @@ export default class FiatStore {
public formatAmountForDisplay = (input: string | number) => {
const { symbol, space, rtl, separatorSwap } = this.getSymbol();
const amount = separatorSwap
? this.numberWithDecimals(input)
: this.numberWithCommas(input);
? numberWithDecimals(input)
: numberWithCommas(input);

if (rtl) return `${amount}${space ? ' ' : ''}${symbol}`;
return `${symbol}${space ? ' ' : ''}${amount}`;
Expand Down
8 changes: 5 additions & 3 deletions stores/PosStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { action, observable } from 'mobx';
import EncryptedStorage from 'react-native-encrypted-storage';
import ReactNativeBlobUtil from 'react-native-blob-util';
import BigNumber from 'bignumber.js';
import { v4 as uuidv4 } from 'uuid';

import { SATS_PER_BTC } from './UnitsStore';
import FiatStore from './FiatStore';
import SettingsStore, { PosEnabled } from './SettingsStore';

import Order from '../models/Order';
import { v4 as uuidv4 } from 'uuid';
import FiatStore from './FiatStore';

import { SATS_PER_BTC } from '../utils/UnitsUtils';

export interface orderPaymentInfo {
orderId: string;
Expand Down
2 changes: 2 additions & 0 deletions stores/SettingsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ interface DisplaySettings {
displayNickname?: boolean;
bigKeypadButtons?: boolean;
showAllDecimalPlaces?: boolean;
removeDecimalSpaces?: boolean;
showMillisatoshiAmounts?: boolean;
}

Expand Down Expand Up @@ -1106,6 +1107,7 @@ export default class SettingsStore {
displayNickname: false,
bigKeypadButtons: false,
showAllDecimalPlaces: false,
removeDecimalSpaces: false,
showMillisatoshiAmounts: true
},
pos: {
Expand Down
37 changes: 20 additions & 17 deletions stores/UnitsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import EncryptedStorage from 'react-native-encrypted-storage';

import SettingsStore from './SettingsStore';
import FiatStore from './FiatStore';
import FeeUtils from './../utils/FeeUtils';

type Units = 'sats' | 'BTC' | 'fiat';
import {
SATS_PER_BTC,
numberWithCommas,
numberWithDecimals
} from '../utils/UnitsUtils';
import FeeUtils from '../utils/FeeUtils';

// 100_000_000
export const SATS_PER_BTC = 100000000;
type Units = 'sats' | 'BTC' | 'fiat';

const UNIT_KEY = 'zeus-units';

Expand Down Expand Up @@ -94,7 +97,7 @@ export default class UnitsStore {
};
} else if (units === 'sats') {
return {
amount: this.fiatStore.numberWithCommas(absValueSats),
amount: numberWithCommas(absValueSats),
unit: 'sats',
negative,
plural: !(Number(value) === 1 || Number(value) === -1)
Expand Down Expand Up @@ -134,8 +137,8 @@ export default class UnitsStore {

return {
amount: separatorSwap
? this.fiatStore.numberWithDecimals(amount)
: this.fiatStore.numberWithCommas(amount),
? numberWithDecimals(amount)
: numberWithCommas(amount),
unit: 'fiat',
symbol,
negative,
Expand Down Expand Up @@ -177,9 +180,9 @@ export default class UnitsStore {
Number(wholeSats || 0) / SATS_PER_BTC
)}`;
} else if (units === 'sats') {
const sats = `${
this.fiatStore.numberWithCommas(wholeSats || value) || 0
} ${Number(value) === 1 || Number(value) === -1 ? 'sat' : 'sats'}`;
const sats = `${numberWithCommas(wholeSats || value) || 0} ${
Number(value) === 1 || Number(value) === -1 ? 'sat' : 'sats'
}`;
return sats;
} else if (units === 'fiat' && fiat) {
if (this.fiatStore.fiatRates) {
Expand All @@ -197,8 +200,8 @@ export default class UnitsStore {
).toFixed(2);

const formattedAmount = separatorSwap
? this.fiatStore.numberWithDecimals(amount)
: this.fiatStore.numberWithCommas(amount);
? numberWithDecimals(amount)
: numberWithCommas(amount);

if (rtl) {
return `${formattedAmount}${space ? ' ' : ''}${symbol}`;
Expand Down Expand Up @@ -231,9 +234,9 @@ export default class UnitsStore {
return `₿${FeeUtils.toFixed(Number(value || 0))}`;
} else if (units === 'sats') {
const [wholeSats] = value.toString().split('.');
const sats = `${
this.fiatStore.numberWithCommas(wholeSats || value) || 0
} ${Number(value) === 1 || Number(value) === -1 ? 'sat' : 'sats'}`;
const sats = `${numberWithCommas(wholeSats || value) || 0} ${
Number(value) === 1 || Number(value) === -1 ? 'sat' : 'sats'
}`;
return sats;
} else if (units === 'fiat' && fiat) {
if (this.fiatStore.fiatRates) {
Expand All @@ -250,8 +253,8 @@ export default class UnitsStore {
).toFixed(2);

const formattedAmount = separatorSwap
? this.fiatStore.numberWithDecimals(amount)
: this.fiatStore.numberWithCommas(amount);
? numberWithDecimals(amount)
: numberWithCommas(amount);

if (rtl) {
return `${formattedAmount}${space ? ' ' : ''}${symbol}`;
Expand Down
10 changes: 10 additions & 0 deletions utils/AddressUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ jest.mock('react-native-encrypted-storage', () => ({
clear: jest.fn(() => Promise.resolve())
}));

jest.mock('../stores/Stores', () => ({
SettingsStore: {
settings: {
display: {
removeDecimalSpaces: false
}
}
}
}));

import AddressUtils from './AddressUtils';
import { walletrpc } from '../proto/lightning';

Expand Down
2 changes: 1 addition & 1 deletion utils/AddressUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const bitcoin = require('bitcoinjs-lib');

import Base64Utils from '../utils/Base64Utils';

import { SATS_PER_BTC } from '../stores/UnitsStore';
import { SATS_PER_BTC } from '../utils/UnitsUtils';

import { walletrpc } from '../proto/lightning';

Expand Down
14 changes: 12 additions & 2 deletions utils/UnitsUtils.test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
jest.mock('../stores/Stores', () => ({
SettingsStore: {
settings: {
display: {
removeDecimalSpaces: false
}
}
}
}));

import { getDecimalPlaceholder } from './UnitsUtils';

describe('UnitsUtils', () => {
describe('getDecimalPlaceholder', () => {
it('Returns string and count properly', () => {
expect(getDecimalPlaceholder('1231.2', 'BTC')).toEqual({
string: '0000000',
string: '0 000 000',
count: 7
});
expect(getDecimalPlaceholder('1231.', 'BTC')).toEqual({
string: '00000000',
string: '00 000 000',
count: 8
});

Expand Down
Loading

0 comments on commit ec5b99a

Please sign in to comment.