Projekt

Obecné

Profil

Stáhnout (8.02 KB) Statistiky
| Větev: | Tag: | Revize:
1 b5ac7218 Fantič
import React, { useCallback, useEffect, useState } from "react"
2 917be067 Fantič
import { log } from "../logging/logger"
3
import { DrawerScreenProps } from "@react-navigation/drawer"
4 f22a2126 Michal Schwob
import {
5
  Box,
6
  Button,
7
  ChevronDownIcon,
8
  ChevronUpIcon,
9
  Flex,
10
  HStack,
11
  MinusIcon,
12
  Popover,
13
  Switch,
14
  Text,
15
  VStack,
16
  useToast,
17
  KeyboardAvoidingView
18
} from "native-base"
19 917be067 Fantič
import { SortOptions } from "../types/general"
20 b225ffee Fantič
import { Note } from "../types/note"
21
import NotesListView from "../components/notes/NotesListView"
22 bb690a9a Fantič
import { useDispatch, useSelector } from "react-redux"
23
import { AppDispatch, RootState } from "../stores/store"
24
import LoadingBox from "../components/loading/LoadingBox"
25 2135f53d Fantič
import { createNote, getAllNotes } from "../stores/actions/notesThunks"
26 a62d7c92 Michal Schwob
import { RootStackParamList } from "./Navigation"
27 f386a4fe Fantič
import { ErrorToast } from "../components/toast/ErrorToast"
28 293f99f8 Fantič
import { InfoToast } from "../components/toast/InfoToast"
29
30 f22a2126 Michal Schwob
import {Dimensions, Platform} from "react-native";
31 760dd761 Fantič
32 a62d7c92 Michal Schwob
const NotesViewPage = ({ navigation }: DrawerScreenProps<RootStackParamList, 'Notes'>) => {
33 917be067 Fantič
34 293f99f8 Fantič
  const { notes, notesLoading, requestPending, triggerRefresh } = useSelector((state: RootState) => state.noteViewState);
35 2135f53d Fantič
36 bb690a9a Fantič
  const dispatch = useDispatch<AppDispatch>();
37
38 917be067 Fantič
  const [isSortOpen, setIsSortOpen] = useState(false);
39
40
  const [myCommentsCheck, setMyCommentsCheck] = useState(false);
41
  const [generalCommentsCheck, setGeneralCommentsCheck] = useState(true);
42
43 f386a4fe Fantič
  const lastError = useSelector((state: RootState) => state.noteViewState.lastError)
44
  const toast = useToast();
45
46
  useEffect(() => {
47 9814562f Fantič
    if (lastError) {
48
      toast.closeAll()
49
      toast.show({
50
        render: ({
51
          id
52
        }) => {
53
          return <ErrorToast headerText={"Error"} text={lastError} onClose={() => toast.close(id)} />;
54
        },
55
        duration: 3000
56
      });
57
    }
58 f386a4fe Fantič
  }, [lastError])
59
60 917be067 Fantič
  const [sortSettings, setSortSettings] = useState({
61
    items: SortOptions.None,
62
    date: SortOptions.None
63
  });
64
65 760dd761 Fantič
  const handleSortChanged = useCallback((key: "items" | "date", sortSettings: any) => {
66 917be067 Fantič
    let currentState = sortSettings[key];
67 9814562f Fantič
    let otherKey = "items"
68
69
    if (key == "items") {
70
      otherKey = "date"
71
    }
72
73 917be067 Fantič
    if (currentState == SortOptions.None) {
74
      setSortSettings({
75
        ...sortSettings,
76 9814562f Fantič
        [key]: SortOptions.Asc,
77
        [otherKey]: SortOptions.None
78 917be067 Fantič
      })
79
    }
80
    else if (currentState == SortOptions.Asc) {
81
      setSortSettings({
82
        ...sortSettings,
83 9814562f Fantič
        [key]: SortOptions.Desc,
84
        [otherKey]: SortOptions.None
85 917be067 Fantič
      })
86
    }
87
    else {
88
      setSortSettings({
89
        ...sortSettings,
90 9814562f Fantič
        [key]: SortOptions.None,
91
        [otherKey]: SortOptions.None
92 917be067 Fantič
      })
93
    }
94 b5ac7218 Fantič
  }, [setSortSettings]);
95 917be067 Fantič
96 9814562f Fantič
  const getSortIcon = (sortOption: SortOptions, size: string, color?: string) => {
97 917be067 Fantič
    switch (sortOption) {
98
      case SortOptions.Asc:
99 9814562f Fantič
        return <ChevronUpIcon size={size} color={color} />;
100 917be067 Fantič
      case SortOptions.Desc:
101 9814562f Fantič
        return <ChevronDownIcon size={size} color={color} />;
102 917be067 Fantič
      default:
103 9814562f Fantič
        return <MinusIcon size={size} color={color} />;
104 917be067 Fantič
    }
105
  };
106
107 3a226033 Fantič
  // trigger refresh on triggerRefresh increment
108 bb690a9a Fantič
  useEffect(() => {
109
    log.debug("NotesViewPage", "useEffect", "getNotes");
110
    getNotes();
111 3a226033 Fantič
  }, [triggerRefresh])
112 bb690a9a Fantič
113
  // general comments check changed
114
  useEffect(() => {
115 2135f53d Fantič
    if (!notesLoading) {
116 bb690a9a Fantič
      log.debug("NotesViewPage", "useEffect", "getNotes");
117
      getNotes();
118
    }
119
  }, [generalCommentsCheck, myCommentsCheck])
120
121
122 bc25708c Fantič
  const getNotes = useCallback(() => {
123 bb690a9a Fantič
    dispatch(getAllNotes({
124
      myComments: myCommentsCheck,
125
      generalComments: generalCommentsCheck,
126
      sortOptions: sortSettings
127
    }));
128 bc25708c Fantič
  }, [myCommentsCheck, generalCommentsCheck, sortSettings]);
129 917be067 Fantič
130
131 bc25708c Fantič
  const handleCreateComment = useCallback((newComment: string, replyingTo: { messageId: string; userName: string } | null) => {
132 2135f53d Fantič
    console.log(newComment, replyingTo)
133 917be067 Fantič
134 2135f53d Fantič
    if (!requestPending) {
135 3a226033 Fantič
      // creating new comment
136 293f99f8 Fantič
      toast.show({
137
        render: ({
138 9814562f Fantič
          id
139 293f99f8 Fantič
        }) => {
140 9814562f Fantič
          return <InfoToast text={"Adding note"} onClose={() => toast.close(id)} />;
141 293f99f8 Fantič
        },
142
        duration: 2000
143 9814562f Fantič
      });
144 2135f53d Fantič
      if (replyingTo != null) {
145
        dispatch(createNote({
146
          newNote: { note: newComment, reply_to: replyingTo.messageId } as Note
147 3a226033 Fantič
        }))
148
      }
149 2135f53d Fantič
      else {
150 3a226033 Fantič
        dispatch(createNote({
151 2135f53d Fantič
          newNote: { note: newComment } as Note
152 3a226033 Fantič
        }))
153
      }
154 2135f53d Fantič
    }
155 bc25708c Fantič
  }, [dispatch, createNote]);
156
157 bb690a9a Fantič
158 2135f53d Fantič
159 b225ffee Fantič
  return (
160 f22a2126 Michal Schwob
161
        <Box>
162
          <VStack>
163
            <Flex direction="row" align="flex-start" justifyContent="space-between" marginTop={1} marginLeft={2.5} marginRight={2.5}>
164
              <Text fontWeight="semibold" mt={3} ml={2} fontSize="md" color="primary.500">General comments</Text>
165
              <Switch isChecked={generalCommentsCheck} onValueChange={() => { if (!notesLoading) setGeneralCommentsCheck(!generalCommentsCheck) }} size="md" marginRight={2} />
166
            </Flex>
167
            <Flex direction="row" align="flex-start" justifyContent="space-between" marginTop={0} marginLeft={2.5} marginRight={2.5}>
168
              <Text fontWeight="semibold" mt={3} ml={2} fontSize="md" color="primary.500" >My comments</Text>
169
              <Switch padding={0} isChecked={myCommentsCheck} onValueChange={() => { if (!notesLoading) setMyCommentsCheck(!myCommentsCheck) }} size="md" marginRight={2} />
170
            </Flex>
171
            <Popover // @ts-ignore
172
              trigger={triggerProps => {
173
                return <Button marginLeft={4} marginBottom={2} width={150} backgroundColor="secondary.500" {...triggerProps} onPress={() => setIsSortOpen(true)}
174
                  borderRadius={7}
175
                  rightIcon={(sortSettings.date != SortOptions.None || sortSettings.items != SortOptions.None) ? (getSortIcon(sortSettings.date != SortOptions.None ? sortSettings.date : sortSettings.items, "xs", "primary.500")) : undefined}
176 9814562f Fantič
                >
177 f22a2126 Michal Schwob
                  <Text fontSize={14} color="primary.500">
178
                    Sort {(sortSettings.date != SortOptions.None || sortSettings.items != SortOptions.None) ? (sortSettings.date != SortOptions.None ? "by date" : "by items") : ""}
179 9814562f Fantič
                  </Text>
180 f22a2126 Michal Schwob
                </Button>;
181
              }} isOpen={isSortOpen} onClose={() => setIsSortOpen(!isSortOpen)}>
182
              <Popover.Content w="48">
183
                <Popover.Arrow />
184
                <Popover.CloseButton onPress={() => setIsSortOpen(false)} />
185
                <Popover.Header><Text fontSize={"md"} color="primary.500">Sort Options</Text></Popover.Header>
186
                <Popover.Body>
187
                  <VStack>
188
                    <Button size="md" variant="outline" onPress={() => handleSortChanged("items", sortSettings)}
189
                      rightIcon={getSortIcon(sortSettings.items, "sm", "primary.500")}
190
                    >
191
                      Items</Button>
192
                    <Button size="md" variant="outline" marginTop={"5%"} onPress={() => handleSortChanged("date", sortSettings)}
193
                      rightIcon={getSortIcon(sortSettings.date, "sm", "primary.500")}>
194
                      Date</Button>
195
                  </VStack>
196
                </Popover.Body>
197
                <Popover.Footer justifyContent="flex-end">
198
                  <Button.Group space={2}>
199
                    <Button colorScheme="coolGray" variant="ghost" onPress={() => setIsSortOpen(false)}>
200
                      Cancel
201
                    </Button>
202
                    <Button backgroundColor={"secondary.500"} onPress={() => { setIsSortOpen(false); getNotes() }}>
203
                      <Text color="primary.500">
204
                        Save
205
                      </Text>
206
                    </Button>
207
                  </Button.Group>
208
                </Popover.Footer>
209
              </Popover.Content>
210
            </Popover>
211
            {
212
              notesLoading ? (
213
                <LoadingBox text="Loading notes" />
214
              )
215
                :
216
                (<NotesListView height={Dimensions.get('window').height - 400} notes={notes} navigation={navigation} handleCreateComment={handleCreateComment} requestPending={requestPending} />)
217
            }
218
219
220
          </VStack>
221
        </Box>
222 917be067 Fantič
  );
223
}
224
225
export default NotesViewPage;