diff --git a/src/game/interface/details/marketplace/DepthChart.js b/src/game/interface/details/marketplace/DepthChart.js index 0a0791548..9e8eec45a 100644 --- a/src/game/interface/details/marketplace/DepthChart.js +++ b/src/game/interface/details/marketplace/DepthChart.js @@ -24,7 +24,7 @@ import useOrderList from '~/hooks/useOrderList'; import useScreenSize from '~/hooks/useScreenSize'; import useStore from '~/hooks/useStore'; import formatters from '~/lib/formatters'; -import { formatFixed, formatPrice, getCrewAbilityBonuses, nativeBool } from '~/lib/utils'; +import { formatFixed, formatPrice, fromLocal, getCrewAbilityBonuses, nativeBool } from '~/lib/utils'; import theme, { hexToRGB } from '~/theme'; import { formatResourceAmount } from '../../hud/actionDialogs/components'; @@ -547,11 +547,8 @@ const MarketplaceDepthChart = ({ lot, marketplace, marketplaceOwner, resource }) }, [baseMarketplaceFee, feeReductionBonus, feeEnforcementBonus]); const [quantity, setQuantity] = useState(); - const [limitPrice, setLimitPrice] = useState(); + const [limitPrice, setLimitPrice] = useState(0); - useEffect(() => { - setLimitPrice(0); - }, [mode, type]); const createOrder = useCallback(() => { onSetAction('MARKETPLACE_ORDER', { @@ -576,7 +573,9 @@ const MarketplaceDepthChart = ({ lot, marketplace, marketplaceOwner, resource }) const handleChangeLimitPrice = useCallback((price, blur = false) => { if (blur) { - if ((mode === 'buy' && price >= ask) || (mode === 'sell' && price <= bid)) { + // convert local formatted price to standard value + const _price = fromLocal(price); + if ((mode === 'buy' && _price >= ask) || (mode === 'sell' && _price <= bid)) { setType('market'); return; } @@ -602,7 +601,7 @@ const MarketplaceDepthChart = ({ lot, marketplace, marketplaceOwner, resource }) }, [buyOrders, mode, quantity, sellOrders]); const totalLimitPrice = useMemo(() => { - return (limitPrice || 0) * quantity; + return (fromLocal(limitPrice) || 0) * quantity; }, [limitPrice, quantity]); const fee = useMemo(() => { @@ -671,6 +670,8 @@ const MarketplaceDepthChart = ({ lot, marketplace, marketplaceOwner, resource }) history.push(`/marketplace/${asteroidId}/${lotIndex}`); }, [lot]); + console.log('avgMarketPrice: ', avgMarketPrice); + return (
@@ -871,7 +872,8 @@ const MarketplaceDepthChart = ({ lot, marketplace, marketplaceOwner, resource }) onChange={(e) => handleChangeLimitPrice(e.currentTarget.value)} onBlur={(e) => handleChangeLimitPrice(e.currentTarget.value, true)} placeholder="Specify Price" - value={limitPrice || ''} /> + type="string" + value={limitPrice} /> )} diff --git a/src/game/interface/hud/actionDialogs/MarketplaceOrder.js b/src/game/interface/hud/actionDialogs/MarketplaceOrder.js index c119838a7..d728ea71c 100644 --- a/src/game/interface/hud/actionDialogs/MarketplaceOrder.js +++ b/src/game/interface/hud/actionDialogs/MarketplaceOrder.js @@ -17,7 +17,7 @@ import useOrderList from '~/hooks/useOrderList'; import useSwayBalance from '~/hooks/useSwayBalance'; import formatters from '~/lib/formatters'; import actionStages from '~/lib/actionStages'; -import { reactBool, formatFixed, formatTimer, getCrewAbilityBonuses, locationsArrToObj, formatPrice } from '~/lib/utils'; +import { reactBool, formatFixed, toLocale, fromLocal, formatTimer, getCrewAbilityBonuses, locationsArrToObj, formatPrice } from '~/lib/utils'; import theme, { hexToRGB } from '~/theme'; import { ActionDialogInner, useAsteroidAndLot } from '../ActionDialog'; import { @@ -198,6 +198,7 @@ const MarketplaceOrder = ({ preselect, ...props }) => { + console.log('MarketplaceOrder, preselect: ', preselect); const resource = Product.TYPES[resourceId] || {}; const resourceByMass = !resource?.isAtomic; const { data: exchangeController } = useHydratedCrew(exchange.Control?.controller?.id); @@ -336,7 +337,7 @@ const MarketplaceOrder = ({ }, [buyOrders, exchange, feeEnforcementBonus, feeReductionBonus, mode, quantity, sellOrders, type]); const totalLimitPrice = useMemo(() => { - return (limitPrice || 0) * quantity; + return (fromLocal(limitPrice) || 0) * quantity; }, [limitPrice, quantity]); // maker = limit order @@ -363,7 +364,7 @@ const MarketplaceOrder = ({ ? undefined : { label: type === 'limit' ? 'Maker Fee' : 'Taker Fee', - value: <> {feeTotal.toLocaleString()} ({formatFixed(100 * feeRate, 1)}%), + value: <> {feeTotal.toLocaleString()} ({toLocale(100 * feeRate, 1)}%), direction: feeRate === baseFeeRate ? 0 : (feeRate > baseFeeRate ? -1 : 1), isTimeStat: true, // (to reverse direction of good/bad) tooltip: feeRate !== baseFeeRate && ( @@ -446,7 +447,7 @@ const MarketplaceOrder = ({ cancelBuyOrder({ amount: quantityToUnits(quantity), buyer: { id: crew?.id, label: crew?.label }, - price: limitPrice, + price: fromLocal(limitPrice), product: resourceId, destination: { id: storage?.id, label: storage?.label }, destinationSlot: storageInventory?.slot, @@ -458,7 +459,7 @@ const MarketplaceOrder = ({ amount: quantityToUnits(quantity), seller: { id: crew?.id, label: crew?.label }, product: resourceId, - price: limitPrice, + price: fromLocal(limitPrice), origin: { id: storage?.id, label: storage?.label }, originSlot: storageInventory?.slot, }) @@ -485,7 +486,7 @@ const MarketplaceOrder = ({ const vars = { product: resourceId, amount: quantityToUnits(quantity), - price: limitPrice + price: fromLocal(limitPrice) }; if (mode === 'buy') { createBuyOrder({ @@ -524,15 +525,11 @@ const MarketplaceOrder = ({ setQuantity(input); }, [mode, totalForSale, totalForBuy, type]); - const handleChangeLimitPrice = useCallback((e) => { - setLimitPrice(Number(e.currentTarget.value)); - }, []); - const matchBestLimitOrder = useCallback((e) => { if (mode === 'buy') { - setLimitPrice(buyOrders[0]?.price || sellOrders[sellOrders.length - 1].price); + setLimitPrice(toLocale(buyOrders[0]?.price || sellOrders[sellOrders.length - 1].price)); } else { - setLimitPrice(sellOrders[sellOrders.length - 1].price); + setLimitPrice(toLocale(sellOrders[sellOrders.length - 1].price)); } }, [mode, buyOrders, sellOrders]); @@ -677,7 +674,7 @@ const MarketplaceOrder = ({ {type === 'market' && ( - Max {((mode === 'buy' ? totalForSale : totalForBuy) || 0).toLocaleString()}{resourceByMass ? ' kg' : ''} + Max {(toLocale(mode === 'buy' ? totalForSale : totalForBuy) || 0)}{resourceByMass ? ' kg' : ''} )} {type === 'limit' && mode === 'sell' && ( In Inventory {formatResourceAmount(amountInInventory || 0, resourceId)} @@ -705,9 +702,10 @@ const MarketplaceOrder = ({ disabled={isCancellation || type === 'market' || stage !== actionStages.NOT_STARTED} style={type === 'market' ? { backgroundColor: `rgba(${hexToRGB(theme.colors.disabledBackground)}, 0.2)` } : {}} min={0} - onChange={handleChangeLimitPrice} - type="number" - value={type === 'market' ? avgMarketPrice : limitPrice} /> + onChange={(e) => setLimitPrice(e.currentTarget.value)} + onBlur={(e) => setLimitPrice(e.currentTarget.value, true)} + type="string" + value={type === 'market' ? toLocale(avgMarketPrice, 4) : limitPrice} /> @@ -806,7 +804,7 @@ const MarketplaceOrder = ({ {!(type === 'limit' && mode === 'sell' && isCancellation) && ( - {type === 'market' && (mode === 'buy' ? '-' : '+')}{formatFixed(total || 0)} + {type === 'market' && (mode === 'buy' ? '-' : '+')}{toLocale(total || 0)} )} diff --git a/src/lib/utils.js b/src/lib/utils.js index 8f2d92936..2a4e18fdf 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -1,9 +1,15 @@ import esb from 'elastic-builder'; import { Crew, Entity, Lot, Permission, Processor, Time } from '@influenceth/sdk'; import trim from 'lodash/trim'; +import numeral from 'numeral'; +import * as locales from 'numeral/locales'; import { BioreactorBuildingIcon, ManufactureIcon, RefineIcon } from '~/components/Icons'; +const getLocale = () => { + return ((navigator && navigator.language) || 'en').split('-')[0]; +}; + const timerIncrements = { d: 86400, h: 3600, m: 60, s: 1 }; export const formatTimer = (secondsRemaining, maxPrecision = null) => { if (isNaN(secondsRemaining)) return ''; @@ -25,6 +31,18 @@ export const formatFixed = (value, maximumFractionDigits = 0) => { return (Math.round((value || 0) * div) / div).toLocaleString(); }; +// Get the numeric value from the specified locallized value +export const fromLocal = (value) => { + numeral.locale(getLocale()); + return numeral(value).value(); +} + +export const toLocale = (value, minimumFractionDigits = 0) => { + if (!value) return 0; + const _value = (typeof value === 'string') ? fromLocal(value) : value; + return _value.toLocaleString(getLocale(), { minimumFractionDigits }); +}; + export const formatPrecision = (value, maximumPrecision = 0) => { const allowedDecimals = Math.max(0, maximumPrecision - Math.ceil(Math.log10(Math.abs(value)))); if (isNaN(allowedDecimals)) { console.log('is nan', value, maximumPrecision); } @@ -47,7 +65,7 @@ export const formatPrice = (inputSway, { minPrecision = 3, fixedPrecision = 4, f scale = 1; unitLabel = ''; } else { - return Number(sway || 0).toLocaleString(undefined, { minimumFractionDigits: minPrecision, maximumFractionDigits: fixedPrecision }); + return Number(sway || 0).toLocaleString(getLocale(), { minimumFractionDigits: minPrecision, maximumFractionDigits: fixedPrecision }); } const workingUnits = (sway / scale);