Projekt

Obecné

Profil

« Předchozí | Další » 

Revize d281786c

Přidáno uživatelem Fantič před asi 2 roky(ů)

re #10454: ItemView: SetConcordance refactor

Zobrazit rozdíly:

src/components/item/ItemTabBar.tsx
1
import { HStack, CircleIcon, View, ScrollView, Button } from "native-base";
2
import { CertaintyWithColors } from "../../stores/reducers/itemSlice";
3
import { Concordance } from "../../types/item";
4
import LoadingBox from "../loading/loadingBox";
5

  
6
// custom render Tab
7
const ItemTabBar = (props: { navigationState: { routes: any[] }, concordances : Concordance[], index: number, onIndexChange : any }) => {
8

  
9
    const {concordances, onIndexChange, index} = props 
10

  
11
    if (concordances && concordances.length > 0)
12
      return (
13
        <View h="16">
14
          <ScrollView horizontal={true} >
15
            <HStack>
16
              {props.navigationState.routes.map((route, i) => {
17
                return (
18
                  <Button size="lg" key={i}
19
                    variant={index == i ? "subtle" : "outline"}
20
                    rightIcon={<CircleIcon size="2" color={CertaintyWithColors[concordances[i].cert].color} />}
21
                    onPress={() => onIndexChange(i)}
22
                  >
23
                    {concordances[i].id}
24
                  </Button>
25
                );
26
              })}
27
            </HStack>
28
          </ScrollView>
29
        </View>
30
      )
31
    else {
32
      return <LoadingBox text={`Loading concordances...`}></LoadingBox>
33
    }
34
  };
35

  
36
  export default ItemTabBar
src/components/item/ItemView.tsx
21 21
                item && (
22 22
                    <ScrollView>
23 23
                        <VStack>
24
                            <Spacer/>
25
                            <Spacer/>
26 24
                            <Text>id: {item.id}</Text>
27 25
                            <Text>name: {item.workName}</Text>
28 26
                            {
src/pages/ItemViewPage.tsx
1
import React, { useEffect } from "react"
1
import React, { ReactNode, useEffect } from "react"
2 2
import { useDispatch, useSelector } from "react-redux"
3 3
import { AppDispatch, RootState } from "../stores/store"
4
import { getItem, getItemNotes, setConcordances, setSelectedConcordance } from "../stores/actions/itemThunks"
4
import { getItem, getItemNotes, setConcordances } from "../stores/actions/itemThunks"
5 5
import { login } from "../stores/actions/userThunks"
6
import { NavigationState, SceneRendererProps, TabBar, TabView } from "react-native-tab-view"
6
import { NavigationState, SceneMap, SceneRendererProps, TabBar, TabView } from "react-native-tab-view"
7 7
import ItemView from "../components/item/ItemView"
8 8
import { Button, Pressable, View, Text, Icon, CircleIcon, ScrollView, HStack, VStack } from "native-base"
9 9
import { useWindowDimensions } from "react-native"
10 10
import LoadingBox from "../components/loading/loadingBox"
11 11
import { CertaintyWithColors } from "../stores/reducers/itemSlice"
12
import ItemTabBar from "../components/item/ItemTabBar"
12 13

  
13 14

  
14 15
interface ItemViewProps {
15 16
  itemId: string
16 17
}
17 18

  
19

  
18 20
const ItemViewPage = (props: ItemViewProps) => {
19 21

  
20 22
  const layout = useWindowDimensions();
23

  
21 24
  const [routes, setRoutes] = React.useState([
22 25
    // initial tab
23 26
    { key: 'loading', title: 'Loading item...' },
24 27
  ]);
25
  const [loadedScenes, setLoadedScenes] = React.useState({});
26 28

  
29
  // // TODO vyřešit, aby nebyly freezy při přepínání
30
  // const [renderSceneDict, setRenderSceneDict] = React.useState({});
27 31

  
32
  const [index, setIndex] = React.useState(0);
28 33

  
29 34
  const dispatch = useDispatch<AppDispatch>();
30 35

  
31
  const { item, itemLoading, notes, notesLoading, concordances, selectedConcordance } = useSelector((state: RootState) => state.itemViewState)
36
  const { item, itemLoading, notes, notesLoading, concordances } = useSelector((state: RootState) => state.itemViewState)
32 37

  
33 38
  // initial: load main item
34 39
  useEffect(() => {
......
43 48
    if (item && concordances && concordances.length > 0) {
44 49
      let concordanceRoutes = [];
45 50

  
51
      // let _renderSceneDict: any = {};
52

  
46 53
      for (let i = 0; i < concordances.length; i++) {
47 54
        let concordance = concordances[i];
48 55
        concordanceRoutes.push({
49 56
          key: concordance.id,
50 57
          title: concordance.id
51 58
        })
59
        // _renderSceneDict[concordance.id] = <LoadingBox text={`Loading item ${concordance.id}...`}></LoadingBox>;
52 60
      }
61

  
53 62
      setRoutes(concordanceRoutes);
63
      // setRenderSceneDict(_renderSceneDict);
54 64
    }
55 65
  }, [concordances]);
56 66

  
57
  const handleTabChange = (index: number) => {
58
  
59
    dispatch(setSelectedConcordance(index));
60
  };
61

  
62 67
  // selected concordance changes
63 68
  useEffect(() => {
69
    console.log("index changed");
64 70
    if (concordances && concordances.length > 0) {
65
      dispatch(getItem(concordances[selectedConcordance].id));
71
      dispatch(getItem(concordances[index].id));
66 72
    }
67

  
68
  }, [selectedConcordance]);
73
  }, [index]);
69 74

  
70 75
  // item changes
71 76
  useEffect(() => {
72 77
    if (!itemLoading && item && item.id) {
73
      if (selectedConcordance == 0) {
78
      if (index == 0) {
74 79
        dispatch(setConcordances(item.concordances));
75 80
      }
76 81
      // set item notes if item is loaded
......
80 85
    }
81 86
  }, [item]);
82 87

  
83
  // custom render Tab
84
  const _renderTabBar = (props: { navigationState: { routes: any[] } }) => {
85
    if (concordances && concordances.length > 0)
86
      return (
87
        <View h="16">
88
          <ScrollView horizontal={true} >
89
            <HStack>
90
              {props.navigationState.routes.map((route, i) => {
91
                return (
92
                  <Button size="lg" key={i}
93
                    variant={selectedConcordance == i ? "subtle" : "outline"}
94
                    rightIcon={<CircleIcon size="2" color={CertaintyWithColors[concordances[i].cert].color} />}
95
                    onPress={() => handleTabChange(i)}
96
                  >
97
                    {concordances[i].id}
98
                  </Button>
99
                );
100
              })}
101
            </HStack>
102

  
103
          </ScrollView>
104
        </View>
105
      )
106
    else {
107
      return <LoadingBox text={`Loading concordances...`}></LoadingBox>
108
    }
109
  };
110

  
111 88
  return (
112 89
    !concordances || concordances.length < 1 ?
113 90
      <LoadingBox text={`Loading item ${props.itemId}...`}></LoadingBox>
114 91
      :
115 92
      <TabView
116
        renderTabBar={_renderTabBar}
117
        navigationState={{ index: selectedConcordance, routes }}
118
        renderScene={() => (
119
          <ItemView item={item} notes={notes} itemLoading={itemLoading} notesLoading={notesLoading} />
120
        )}
121
        initialLayout={{ width: layout.width }}
93
        renderTabBar={() => ItemTabBar({
94
          navigationState: {
95
            routes: routes,
96
          },
97
          concordances: concordances,
98
          index: index,
99
          onIndexChange: setIndex
100
        })}
101

  
102
        navigationState={{ index, routes }}
103
        renderScene={() => <ItemView item={item} notes={notes} itemLoading={itemLoading} notesLoading={notesLoading} />}
122 104

  
105
        initialLayout={{ width: layout.width }}
123 106
        // prevent default action on index change
124
        onIndexChange={handleTabChange}
107
        onIndexChange={setIndex}
125 108

  
126 109
      />
127 110
  );
src/stores/reducers/itemSlice.ts
13 13

  
14 14
const initialState: ItemViewState = {
15 15
    item: {} as Item,
16
    selectedConcordance: 0,
17 16
    concordances: [],
18 17
    notes: [],
19 18
    lastError: "",
......
25 24
    name: "item",
26 25
    initialState: initialState,
27 26
    reducers: {
28
        setSelectedConcordance: (state, action) => {
29
            state.selectedConcordance = action.payload.selectedConcordance;
30
        },
31 27
        setConcordances: (state, action) => {
32 28
            state.concordances = action.payload.concordances;
33 29
        }
src/types/item.ts
30 30
    item: Item
31 31
    itemLoading: boolean
32 32
    concordances: Concordance[]
33
    selectedConcordance: number
34 33
    notes: Note[]
35 34
    notesLoading: boolean
36 35
    lastError?: string

Také k dispozici: Unified diff