Untitled

mail@pastecode.io avatar
unknown
plain_text
7 months ago
9.1 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, TouchableOpacity, useWindowDimensions } from 'react-native';
import { FlatList } from 'react-native';
import { useTranslation } from 'react-i18next';

import { useColors } from '../../hooks';
import { useMatriksContext } from '../../context/MatriksStore';
import Icon from '../ui/Icon';
import { toNumber } from 'lodash';
import { useNavigation } from '@react-navigation/native';
import { useEtrader } from '../../context';

const header = (t: any) => (
  <View margin-10 row center>
    {['order', 'Qty', 'BUY', 'SELL', 'Qty', 'orders'].map((label, index) => (
      <Text key={index} marginL-20 marginR-20 secondaryText body2>
        {t(label)}
      </Text>
    ))}
  </View>
);

const DepthStats = ({ symbolCode, showInfo }: any) => {
  const { colors }: any = useColors();
  const dataListRef = useRef([]);
  const [data, setData]: any = useState([]);
  const { t } = useTranslation();
  const navigation = useNavigation();
  const [depthData, setDepthData]: any = useMatriksContext();
  const [dataStats, setDataStats]: any = useState([]);
  const [priceLevelsSize, setPriceLevelsSize] = useState(5);
  const [showAllLevels, setShowAllLevels] = useState(false);
  const {
    store: { isLogin },
  } = useEtrader();

  const onSellStock = () => {
    if (isLogin) {
      navigation.navigate('orders', {
        screen: 'ordersBuySell',
        params: { symbol: { symbolCode: symbolCode, type: 'Sell' } },
      });
    } else {
      navigation.navigate('loginHome' as never, {
        navigateTo: {
          tab: 'orders',
          routeName: 'ordersBuySell',
          params: { symbol: { symbolCode: symbolCode, type: 'Sell' } },
        },
      });
    }
  };

  const onBuyStock = () => {
    if (isLogin) {
      navigation.navigate('orders', {
        screen: 'ordersBuySell',
        params: { symbol: { symbolCode: symbolCode, type: 'Buy' } },
      });
    } else {
      navigation.navigate('loginHome' as never, {
        navigateTo: {
          tab: 'orders',
          routeName: 'ordersBuySell',
          params: { symbol: { symbolCode: symbolCode, type: 'Buy' } },
        },
      });
    }
  };

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

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

  useEffect(() => {
    if (symbolCode) {
      Matriks.subscribeDepthStats(symbolCode, (resp: any) => {
        if (resp) {
          setDataStats(resp);
        }
      });
      return () => {
        Matriks.unsubscribeDepthStats();
      };
    }
  }, [symbolCode]);

  const toggleSize = () => {
    setPriceLevelsSize(priceLevelsSize === 5 ? 20 : 5);
    setShowAllLevels(!showAllLevels);
  };
  let { width } = useWindowDimensions();

  const widthX = width - 270 - 32;
  const maxBuy = Math.max(...data.map((item: any) => parseFloat(item?.bidQuantity.replace(',', ''))));
  const maxSell = Math.max(...data.map((item: any) => parseFloat(item?.askQuantity.replace(',', ''))));
  const orderBuySum = data.reduce((acc: any, item: any) => acc + toNumber(item.bidOrderCount), 0);
  const orderSellSum = data.reduce((acc: any, item: any) => acc + toNumber(item.askOrderCount), 0);
  const x = widthX / maxBuy;
  const y = widthX / maxSell;
  const renderItem = ({ item, index }: any) => {
    return (
      <View row marginV-10 marginH-16>
        <View style={styles(colors).verticalBorder} />
        <View row flex-1>
          <Text flex-1 body-2 primaryText>
            {item?.bidOrderCount}
          </Text>
          <Text body-2 marginR-80 primaryText>
            {item?.bidQuantity}
          </Text>
          <View style={styles(colors).greenColorView} width={x * parseFloat(item?.bidQuantity.replace(',', ''))}>
            <TouchableOpacity onPress={() => onBuyStock()}>
              <Text style={styles(colors).greenColor} key={index} body2>
                {item?.bidPrice}
              </Text>
            </TouchableOpacity>
          </View>
        </View>
        <View row flex-1>
          <View style={styles(colors).redColorView} width={y * parseFloat(item?.askQuantity.replace(',', ''))}>
            <TouchableOpacity onPress={() => onSellStock()}>
              <Text style={styles(colors).redColor} key={index} body2>
                {item?.askPrice}
              </Text>
            </TouchableOpacity>
          </View>

          <Text body-2 primaryText flex-1 marginL-80>
            {item?.askQuantity}
          </Text>
          <Text body-2 primaryText flex-0 style={styles(colors).textAlignRight}>
            {item?.askOrderCount}
          </Text>
        </View>
      </View>
    );
  };
  const renderInfo = () => {
    return (
      <View center style={styles(colors).topBorder}>
        <View row>
          <View row flex-1 margin-16>
            <Text flex-0 primaryText style={styles(colors).sumText}>
              {orderBuySum}
            </Text>
            <Text flex-1 center primaryText style={styles(colors).sumText}>
              {dataStats?.bidQuantity}
            </Text>
            <TouchableOpacity onPress={() => onBuyStock()}>
              <Text flex-0 style={styles(colors).priceBuySum}>
                {dataStats?.bidPrice}
              </Text>
            </TouchableOpacity>
          </View>

          <View flex-1 row margin-16>
            <TouchableOpacity onPress={() => onSellStock()}>
              <Text style={styles(colors).priceSellSum}>{dataStats?.askPrice}</Text>
            </TouchableOpacity>
            <Text flex-1 center primaryText style={styles(colors).sumText}>
              {dataStats?.askQuantity}
            </Text>
            <Text flex-0 primaryText>
              {orderSellSum}
            </Text>
          </View>
        </View>
      </View>
    );
  };
  return (
    <>
      {data && data.length > 0 && (
        <View marginB-20>
          {header(t)}
          <FlatList
            onScroll={e => e.preventDefault()}
            showsVerticalScrollIndicator={false}
            data={data}
            renderItem={renderItem}
            nestedScrollEnabled={true}
            scrollEnabled={false}
            keyExtractor={(item, index) => `item-${index}`}
          />
          {showInfo && renderInfo()}
          {data.length >= 5 && (
            <View marginT-16>
              <TouchableOpacity onPress={toggleSize}>
                <View row center>
                  <Text style={styles(colors).textColor}>
                    {showAllLevels ? t('top5PriceLevels') : t('allPriceLevels')}
                  </Text>
                  {!showAllLevels && (
                    <Icon
                      style={styles(colors).arrowStyle}
                      name="arrowRight"
                      width={6}
                      height={10}
                      fill={colors.action}
                    />
                  )}
                </View>
              </TouchableOpacity>
            </View>
          )}
        </View>
      )}
    </>
  );
};

export default memo(DepthStats);

const styles = (colors: any) =>
  StyleSheet.create({
    redColor: {
      color: colors.redPrice,
      width: 100,
      paddingLeft: 12,
    },
    greenColor: {
      color: colors.greenPrice,
      paddingRight: 12,
      justifyContent: 'center',
      textAlign: 'right',
      width: 100,
    },
    redColorView: {
      backgroundColor: colors.darkRedBg,
      position: 'absolute',
      left: 0,
      height: 24,
      justifyContent: 'center',
      alignItems: 'center',
    },
    greenColorView: {
      backgroundColor: colors.darkGreenBg,
      position: 'absolute',
      right: 0,
      height: 24,
      justifyContent: 'center',
      alignItems: 'center',
    },
    topBorder: {
      borderTopWidth: 1,
      borderColor: colors.white20,
    },
    textAlignRight: { textAlign: 'right' },
    sumText: { fontWeight: '500', fontSize: 12 },
    verticalBorder: {
      borderRightWidth: 1,
      borderColor: colors.white20,
    },
    priceBuySum: {
      color: colors.greenPrice,
      fontSize: 12,
      fontWeight: '500',
    },
    priceSellSum: {
      color: colors.redPrice,
      fontSize: 12,
      fontWeight: '500',
    },
    textColor: {
      color: colors.action,
      fontSize: 12,
    },
    arrowStyle: {
      marginLeft: 10,
      marginTop: 3,
    },
  });