Projekt

Obecné

Profil

Stáhnout (8.23 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 9abf01c3 Michal Schwob
      <KeyboardAvoidingView
161
          behavior={Platform.OS === "ios" ? "padding" : "height"}
162
          keyboardVerticalOffset={Platform.OS === "ios" ? 100 : 80}
163
          style={{ flex: 1 }}
164
          mb={6}
165
      >
166
        <VStack flex={1}>
167 f22a2126 Michal Schwob
            <Flex direction="row" align="flex-start" justifyContent="space-between" marginTop={1} marginLeft={2.5} marginRight={2.5}>
168
              <Text fontWeight="semibold" mt={3} ml={2} fontSize="md" color="primary.500">General comments</Text>
169
              <Switch isChecked={generalCommentsCheck} onValueChange={() => { if (!notesLoading) setGeneralCommentsCheck(!generalCommentsCheck) }} size="md" marginRight={2} />
170
            </Flex>
171
            <Flex direction="row" align="flex-start" justifyContent="space-between" marginTop={0} marginLeft={2.5} marginRight={2.5}>
172
              <Text fontWeight="semibold" mt={3} ml={2} fontSize="md" color="primary.500" >My comments</Text>
173
              <Switch padding={0} isChecked={myCommentsCheck} onValueChange={() => { if (!notesLoading) setMyCommentsCheck(!myCommentsCheck) }} size="md" marginRight={2} />
174
            </Flex>
175
            <Popover // @ts-ignore
176
              trigger={triggerProps => {
177
                return <Button marginLeft={4} marginBottom={2} width={150} backgroundColor="secondary.500" {...triggerProps} onPress={() => setIsSortOpen(true)}
178
                  borderRadius={7}
179
                  rightIcon={(sortSettings.date != SortOptions.None || sortSettings.items != SortOptions.None) ? (getSortIcon(sortSettings.date != SortOptions.None ? sortSettings.date : sortSettings.items, "xs", "primary.500")) : undefined}
180 9814562f Fantič
                >
181 f22a2126 Michal Schwob
                  <Text fontSize={14} color="primary.500">
182
                    Sort {(sortSettings.date != SortOptions.None || sortSettings.items != SortOptions.None) ? (sortSettings.date != SortOptions.None ? "by date" : "by items") : ""}
183 9814562f Fantič
                  </Text>
184 f22a2126 Michal Schwob
                </Button>;
185
              }} isOpen={isSortOpen} onClose={() => setIsSortOpen(!isSortOpen)}>
186
              <Popover.Content w="48">
187
                <Popover.Arrow />
188
                <Popover.CloseButton onPress={() => setIsSortOpen(false)} />
189
                <Popover.Header><Text fontSize={"md"} color="primary.500">Sort Options</Text></Popover.Header>
190
                <Popover.Body>
191
                  <VStack>
192
                    <Button size="md" variant="outline" onPress={() => handleSortChanged("items", sortSettings)}
193
                      rightIcon={getSortIcon(sortSettings.items, "sm", "primary.500")}
194
                    >
195
                      Items</Button>
196
                    <Button size="md" variant="outline" marginTop={"5%"} onPress={() => handleSortChanged("date", sortSettings)}
197
                      rightIcon={getSortIcon(sortSettings.date, "sm", "primary.500")}>
198
                      Date</Button>
199
                  </VStack>
200
                </Popover.Body>
201
                <Popover.Footer justifyContent="flex-end">
202
                  <Button.Group space={2}>
203
                    <Button colorScheme="coolGray" variant="ghost" onPress={() => setIsSortOpen(false)}>
204
                      Cancel
205
                    </Button>
206
                    <Button backgroundColor={"secondary.500"} onPress={() => { setIsSortOpen(false); getNotes() }}>
207
                      <Text color="primary.500">
208
                        Save
209
                      </Text>
210
                    </Button>
211
                  </Button.Group>
212
                </Popover.Footer>
213
              </Popover.Content>
214
            </Popover>
215
            {
216
              notesLoading ? (
217
                <LoadingBox text="Loading notes" />
218
              )
219
                :
220 9abf01c3 Michal Schwob
                (
221
222 f22a2126 Michal Schwob
223 9abf01c3 Michal Schwob
                  <NotesListView notes={notes} navigation={navigation} handleCreateComment={handleCreateComment} requestPending={requestPending} />
224
225
226
                )
227
            }
228 f22a2126 Michal Schwob
229
          </VStack>
230 9abf01c3 Michal Schwob
      </KeyboardAvoidingView>
231 917be067 Fantič
  );
232
}
233
234
export default NotesViewPage;