Untitled

mail@pastecode.io avatarunknown
plain_text
2 months ago
7.4 kB
1
Indexable
Never
import React, { useEffect, useRef, useState, memo } from 'react';
import { Text, View } from 'react-native-ui-lib';
import { Matriks } from '../Matriks';
import { StyleSheet } from 'react-native';
import { FlatList } from 'react-native';
import { useColors } from '../../hooks';
import { useMatriksContext } from '../../context/MatriksStore';
import { useTranslation } from 'react-i18next';
import { toNumber } from 'lodash';

const header = (t: any) => (
  <View margin-10 row>
    <View flex-1 centerV>
      <Text secondaryText body2>
        {t('order')}
      </Text>
    </View>
    <View flex-1 centerV>
      <Text secondaryText body2>
        {t('Qty')}
      </Text>
    </View>
    <View flex-1 centerV>
      <Text secondaryText body2>
        {t('BUY')}
      </Text>
    </View>
    <View flex-1 centerV>
      <Text secondaryText body2>
        {t('SELL')}
      </Text>
    </View>

    <View flex-1 centerV>
      <Text secondaryText body2>
        {t('Qty')}
      </Text>
    </View>

    <View flex-0 centerV>
      <Text secondaryText body2>
        {t('orders')}
      </Text>
    </View>
  </View>
);

const DepthStats = ({ symbolCode, size = 10 }: any) => {
  const { colors } = useColors();
  const dataListRef = useRef([]);
  const [data, setData] = useState([]);
  const { t } = useTranslation();
  const [depthData, setDepthData] = useMatriksContext();

  useEffect(() => {
    if (depthData && depthData?.type === 'depth') {
      const update = { ...depthData };
      dataListRef.current.splice(0, 0, update);
      if (dataListRef.current.length > size) {
        dataListRef.current.pop();
      }
      setData(dataListRef.current);
    }
  }, [depthData]);

  useEffect(() => {
    if (symbolCode) {
      Matriks.subscribeDepth(symbolCode, resp => {
        if (resp?.depthList) {
          resp?.depthList.map(item => setDepthData({ ...item, type: 'depth' }));
        } else {
          setDepthData({ ...resp, type: 'depth' });
        }
      });
      return () => {
        Matriks.unsubscribeDepth();
      };
    }
  }, [symbolCode]);

  const x = 50;
  const y = 50;

  const formattedNumber = num => {
    const numberParts = num.toString().split('.');
    if (numberParts[0].length >= 6) {
      numberParts[0] = numberParts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    }
    return numberParts.join('.');
  };

  const priceBuySum = data.reduce((acc: any, item: any) => acc + toNumber(item.bidPrice), 0);
  const priceSellSum = data.reduce((acc: any, item: any) => acc + toNumber(item.askPrice), 0);
  const orderBuySum = data.reduce((acc: any, item: any) => acc + toNumber(item.askOrderCount), 0);
  const orderSellSum = data.reduce((acc: any, item: any) => acc + toNumber(item.bidOrderCount), 0);
  const quantityBuySum = data.reduce((acc: any, item: any) => acc + toNumber(item.bidQuantity.replace(',', '')), 0);
  const formattedQuantityBuySum = formattedNumber(quantityBuySum);

  const quantitySellSum = data.reduce((acc: any, item: any) => acc + toNumber(item.askQuantity.replace(',', '')), 0);
  const formattedQuantitySellSum = formattedNumber(quantitySellSum);

  const renderItem = ({ item, index }: any) => {
    return (
      <View paddingH-16 style={styles(colors).rowStyles} row>
        <View flex-1 centerV>
          <Text body-2 primaryText>
            {item?.askOrderCount}
          </Text>
        </View>
        <View flex-1 centerV style={styles(colors).askQuantity}>
          <Text body-2 primaryText style={styles(colors).textAlignRight}>
            {item?.askQuantity}
          </Text>
        </View>
        <View row center style={{ position: 'absolute', left: 190 }} marginT-20>
          <View style={styles(colors).greenColorView} width={x * item.bidQuantity}>
            <View>
              <Text style={styles(colors).greenColor} key={index} body2>
                {item?.bidPrice}
              </Text>
            </View>
          </View>
          <View width={1} height="100%" backgroundColor={colors.white20} style={{ position: 'absolute' }} />
          <View style={styles(colors).redColorView} width={y * item.askQuantity}>
            <Text style={styles(colors).redColor} key={index} body2>
              {item?.askPrice}
            </Text>
          </View>
        </View>
        <View flex-1 centerV style={styles(colors).bidQuantity}>
          <Text body-2 primaryText>
            {item?.bidQuantity}
          </Text>
        </View>
        <View flex-1 centerV>
          <Text body-2 primaryText style={styles(colors).textAlignRight}>
            {item?.bidOrderCount}
          </Text>
        </View>
      </View>
    );
  };

  return (
    <>
      {data && data.length > 0 && (
        <View marginB-20 style={styles(colors).container}>
          <FlatList
            onScroll={e => e.preventDefault()}
            ListHeaderComponent={() => header(t)}
            showsVerticalScrollIndicator={false}
            data={data}
            renderItem={renderItem}
            nestedScrollEnabled={true}
            scrollEnabled={false}
            keyExtractor={(item, index) => `item-${index}`}
          />
          <View center style={styles(colors).topBorder}>
            <View marginT-10 marginB-10 row>
              <Text primaryText style={{ fontWeight: 500, fontSize: 12 }} flex-1 center>
                {orderBuySum}
              </Text>
              <Text primaryText style={{ fontWeight: 500, fontSize: 12 }} flex-1 center>
                {formattedQuantityBuySum}
              </Text>
              <Text style={{ color: colors.greenPrice, fontSize: 12 }} flex-1 center>
                {priceBuySum.toFixed(2)}
              </Text>
              <Text style={{ color: colors.redPrice, fontSize: 12 }} flex-1 center>
                {priceSellSum.toFixed(2)}
              </Text>
              <Text primaryText style={{ fontWeight: 500, fontSize: 12 }} flex-1 center>
                {formattedQuantitySellSum}
              </Text>
              <Text primaryText style={{ fontWeight: 500, fontSize: 12 }} flex-1 center>
                {orderSellSum}
              </Text>
            </View>
          </View>
        </View>
      )}
    </>
  );
};

export default memo(DepthStats);

const styles = (colors: any) =>
  StyleSheet.create({
    redColor: {
      color: colors.redPrice,
      width: 70,
      paddingLeft: 10,
    },
    greenColor: {
      color: colors.greenPrice,
      paddingRight: 10,
      justifyContent: 'center',
      textAlign: 'right',
      width: 70,
    },
    redColorView: {
      backgroundColor: colors.darkRedBg,
      backgroundOpacity: 0.6,
      position: 'absolute',
      left: 0,
      marginLeft: 5,
      height: 24,
      justifyContent: 'center',
    },
    greenColorView: {
      backgroundColor: colors.darkGreenBg,
      backgroundOpacity: 0.6,
      position: 'absolute',
      right: 0,

      height: 24,
      justifyContent: 'center',
    },
    askQuantity: {
      position: 'absolute',
      left: 0,
      marginLeft: 60,
      marginTop: 10,
      justifyContent: 'center',
    },
    bidQuantity: {
      position: 'absolute',
      right: 0,
      marginRight: 60,
      marginTop: 10,
      justifyContent: 'center',
    },
    topBorder: {
      borderTopWidth: 1,
      borderColor: colors.white20,
    },
    rowStyles: { height: 40 },
    textAlignRight: { textAlign: 'right' },
  });