Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
6.0 kB
3
Indexable
Never
import React, { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useFocusEffect, useRoute } from '@react-navigation/native';

import { BaseScreen, CustomFlatList } from '../../../components/ui';
import { useEtrader } from '../../../context';
import { StockSymbolRow, Tabbar } from '../../../components/business';
import { Matriks } from '../../../components/Matriks/module';
import TreeMap from '../../../components/business/TreeMap';
import { GetImpactAnalysis } from '../../../api/matriks';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { Text, View } from 'react-native-ui-lib';
import { useColors } from '../../../hooks';
import _ from 'lodash';
import { useWindowDimensions } from 'react-native';

let VIEWABLE_ITEMS: any[] = [];

export function HeatMapDetail() {
  const {
    params: { symbolCode: indexCode },
  }: any = useRoute();

  const [indexData, setIndexData] = useState<any[]>([]);
  let rows: Array<any> = [];
  const { colors } = useColors();
  const { t } = useTranslation();

  const {
    store: { isLogin, theme },
  } = useEtrader();

  const { data: impactAnalysisResponse } = GetImpactAnalysis(indexCode);
  const [selectedTab, setSelectedTab] = useState(0);
  const [treeMapData, setTreeMapData] = useState();
  const [showAllData, setShowAllData] = useState(false);
  const [visibleWatchList, setVisibleWatchList] = useState<any[]>();
  const [symbolWeightData, setSymbolWeightData] = useState<any[]>();

  const data = impactAnalysisResponse?.list?.map((item: any) => item.symbol);

  const getSymbolAndSnapshot = async () => {
    try {
      const response = await Matriks.getSymbolAndSnapshot(indexCode);
      setIndexData(response);
    } catch (error) {
      console.log('getSymbolAndSnapshot error', error);
    }
  };

  useEffect(() => {
    if (indexCode) {
      getSymbolAndSnapshot();
    }
  }, [indexCode]);

  useEffect(() => {
    setShowAllData(false);
    setVisibleWatchList(data?.slice(0, 10) || []);
  }, [impactAnalysisResponse]);

  const onViewableItemsChanged = useCallback(({ viewableItems }: any) => {
    const renew = () => {
      if (!_.isEmpty(viewableItems)) {
        VIEWABLE_ITEMS = viewableItems;
        Matriks.subscribeSymbol(viewableItems, () => {}, []);
      }
    };
    setTimeout(() => {
      renew();
    }, 10);
  }, []);

  useEffect(() => {
    if (data) {
      Matriks.subscribeSymbol(data, () => {}, []);
    }
  }, [data]);

  useFocusEffect(
    useCallback(() => {
      if (VIEWABLE_ITEMS.length !== 0) {
        console.log('SUBSCRIPTION WILL CONTINUE WITH', VIEWABLE_ITEMS);
        Matriks.subscribeSymbol(VIEWABLE_ITEMS, () => {}, []);
      }
      return () => {
        // VIEWABLE_ITEMS = [];
        Matriks.unsubscribe();
      };
    }, []),
  );

  const viewAllSymbols = () =>
    data?.length > 10 ? (
      <TouchableOpacity
        paddingV-16
        onPress={() => {
          const allData = !showAllData;
          setShowAllData(allData);
          setVisibleWatchList(allData ? data : data?.slice(0, 10) || []);
        }}>
        <Text paddingV-8 center color={colors.action} button1>
          {showAllData ? t('hide') : t('viewAll')}
        </Text>
      </TouchableOpacity>
    ) : null;

  const renderSymbolRow = useCallback(
    ({ item, index }: any) => {
      const weight = symbolWeightData[item];
      return (
        <StockSymbolRow
          onChangeRef={(ref: any) => (rows[index] = ref)}
          isLogin={isLogin}
          item={item}
          notShowSecond={false}
          showVolume={false}
          swipeDisable={true}
          screenName="marketSymbolDetail"
          hideRealTime={true}
          heatMapWeightData={weight}
          heatMap={true}
        />
      );
    },
    [symbolWeightData],
  );

  useEffect(() => {
    if (impactAnalysisResponse) {
      const weightData = {};
      impactAnalysisResponse.list.forEach(({ symbol, weight }) => {
        weightData[symbol] = weight;
      });
      setSymbolWeightData(weightData);

      const _treeMapData = impactAnalysisResponse?.list?.map(({ symbol, weight }: any) => {
        let calculatedValue = 0;
        Matriks.subscribeSymbol(
          [symbol],
          response => {
            const dayClose = response?.dayClose;
            const differencePercent = response?.differencePercent;
            calculatedValue = ((weight / 100) * dayClose * differencePercent) / 100;
          },
          [],
        );
        return { name: symbol, value: calculatedValue, percentage: +1.0 };
      });
      setTreeMapData(_treeMapData);
    }
  }, [impactAnalysisResponse]);
  console.log(treeMapData);
  const { bottom } = useWindowDimensions();

  const renderTabContent = () => {
    switch (selectedTab) {
      case 0:
        return treeMapData ? <TreeMap treeMapData={treeMapData} /> : null;

      case 1:
        return (
          <View flex-1 style={{ marginBottom: bottom }}>
            <CustomFlatList
              swipeDisable
              initialItemLength={10}
              onViewableItemsChanged={onViewableItemsChanged}
              // headerView={headerComponent}
              estimatedItemSize={84}
              data={visibleWatchList}
              noCalculateLayout
              footerView={<View marginV-12>{viewAllSymbols()}</View>}
              renderItem={renderSymbolRow}
            />
          </View>
        );

      default:
        return null;
    }
  };

  return (
    <BaseScreen
      theme={theme}
      header={{
        type: 'symbolHeader',
        symbolCode: indexCode,
        symbolDescription: indexData?.symbolDesc,
        price: indexData.last ? indexData?.last : 0,
        notMagnifier: true,
      }}>
      <Tabbar
        customIndicatorWidth
        center
        data={[{ label: t('heatMap') }, { label: t('list') }]}
        setSelectedTab={setSelectedTab}
        selectedTab={selectedTab}
      />
      {renderTabContent()}
    </BaseScreen>
  );
}