kopia lustrzana https://github.com/bugout-dev/moonstream
				
				
				
			Merge branch 'main' into alpha
						commit
						3e14a8cba3
					
				| 
						 | 
				
			
			@ -6,6 +6,7 @@ import {
 | 
			
		|||
  UserProvider,
 | 
			
		||||
  ModalProvider,
 | 
			
		||||
  UIProvider,
 | 
			
		||||
  DataProvider,
 | 
			
		||||
} from "./core/providers";
 | 
			
		||||
import { StripeProvider } from "./core/providers/StripeProvider";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -15,9 +16,11 @@ const AppContext = (props) => {
 | 
			
		|||
      <ModalProvider>
 | 
			
		||||
        <StripeProvider>
 | 
			
		||||
          <ChakraProvider theme={theme}>
 | 
			
		||||
            <UIProvider>
 | 
			
		||||
              <AnalyticsProvider>{props.children}</AnalyticsProvider>
 | 
			
		||||
            </UIProvider>
 | 
			
		||||
            <DataProvider>
 | 
			
		||||
              <UIProvider>
 | 
			
		||||
                <AnalyticsProvider>{props.children}</AnalyticsProvider>
 | 
			
		||||
              </UIProvider>
 | 
			
		||||
            </DataProvider>
 | 
			
		||||
          </ChakraProvider>
 | 
			
		||||
        </StripeProvider>
 | 
			
		||||
      </ModalProvider>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,4 @@
 | 
			
		|||
import React, {
 | 
			
		||||
  useRef,
 | 
			
		||||
  useEffect,
 | 
			
		||||
  useContext,
 | 
			
		||||
  useState,
 | 
			
		||||
  useCallback,
 | 
			
		||||
} from "react";
 | 
			
		||||
import React, { useEffect, useContext, useState, useCallback } from "react";
 | 
			
		||||
import {
 | 
			
		||||
  Flex,
 | 
			
		||||
  Spinner,
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +34,8 @@ import { FaFilter } from "react-icons/fa";
 | 
			
		|||
import useStream from "../core/hooks/useStream";
 | 
			
		||||
import { ImCancelCircle } from "react-icons/im";
 | 
			
		||||
import { previousEvent } from "../core/services/stream.service";
 | 
			
		||||
import { PAGE_SIZE } from "../core/constants";
 | 
			
		||||
import DataContext from "../core/providers/DataProvider/context";
 | 
			
		||||
 | 
			
		||||
const FILTER_TYPES = {
 | 
			
		||||
  ADDRESS: 0,
 | 
			
		||||
| 
						 | 
				
			
			@ -61,11 +57,12 @@ const CONDITION = {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
const EntriesNavigation = () => {
 | 
			
		||||
  const { cursor, setCursor, streamCache, setStreamCache } =
 | 
			
		||||
    useContext(DataContext);
 | 
			
		||||
  const ui = useContext(UIContext);
 | 
			
		||||
  const { isOpen, onOpen, onClose } = useDisclosure();
 | 
			
		||||
  const { subscriptionsCache } = useSubscriptions();
 | 
			
		||||
  const [initialized, setInitialized] = useState(false);
 | 
			
		||||
  const [entries, setEntries] = useState([]);
 | 
			
		||||
  const [newFilterState, setNewFilterState] = useState([
 | 
			
		||||
    {
 | 
			
		||||
      type: FILTER_TYPES.ADDRESS,
 | 
			
		||||
| 
						 | 
				
			
			@ -76,21 +73,27 @@ const EntriesNavigation = () => {
 | 
			
		|||
  ]);
 | 
			
		||||
  const [filterState, setFilterState] = useState([]);
 | 
			
		||||
 | 
			
		||||
  const loadMoreButtonRef = useRef(null);
 | 
			
		||||
 | 
			
		||||
  const {
 | 
			
		||||
    events,
 | 
			
		||||
    eventsIsLoading,
 | 
			
		||||
    eventsRefetch,
 | 
			
		||||
    eventsIsFetching,
 | 
			
		||||
    latestEventsRefetch,
 | 
			
		||||
    nextEventRefetch,
 | 
			
		||||
    previousEventRefetch,
 | 
			
		||||
    streamBoundary,
 | 
			
		||||
    setDefaultBoundary,
 | 
			
		||||
    loadOlderEvents,
 | 
			
		||||
    loadNewerEvents,
 | 
			
		||||
  } = useStream(ui.searchTerm.q);
 | 
			
		||||
    loadPreviousEventHandler,
 | 
			
		||||
    loadNewesEventHandler,
 | 
			
		||||
    loadOlderEventsIsFetching,
 | 
			
		||||
    loadNewerEventsIsFetching,
 | 
			
		||||
    previousEventIsFetching,
 | 
			
		||||
    nextEventIsFetching,
 | 
			
		||||
  } = useStream(
 | 
			
		||||
    ui.searchTerm.q,
 | 
			
		||||
    streamCache,
 | 
			
		||||
    setStreamCache,
 | 
			
		||||
    cursor,
 | 
			
		||||
    setCursor
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (!streamBoundary.start_time && !streamBoundary.end_time) {
 | 
			
		||||
| 
						 | 
				
			
			@ -113,12 +116,6 @@ const EntriesNavigation = () => {
 | 
			
		|||
    previousEventRefetch,
 | 
			
		||||
  ]);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (events) {
 | 
			
		||||
      setEntries(events);
 | 
			
		||||
    }
 | 
			
		||||
  }, [events]);
 | 
			
		||||
 | 
			
		||||
  const setFilterProps = useCallback(
 | 
			
		||||
    (filterIdx, props) => {
 | 
			
		||||
      const newFilterProps = [...newFilterState];
 | 
			
		||||
| 
						 | 
				
			
			@ -214,7 +211,7 @@ const EntriesNavigation = () => {
 | 
			
		|||
      direction="column"
 | 
			
		||||
      flexGrow={1}
 | 
			
		||||
    >
 | 
			
		||||
      {entries && !eventsIsLoading ? (
 | 
			
		||||
      {streamCache && !eventsIsLoading ? (
 | 
			
		||||
        <>
 | 
			
		||||
          <Drawer onClose={onClose} isOpen={isOpen} size="lg">
 | 
			
		||||
            <DrawerOverlay />
 | 
			
		||||
| 
						 | 
				
			
			@ -425,11 +422,10 @@ const EntriesNavigation = () => {
 | 
			
		|||
              //onScroll={(e) => handleScroll(e)}
 | 
			
		||||
            >
 | 
			
		||||
              <Stack direction="row" justifyContent="space-between">
 | 
			
		||||
                {!eventsIsFetching ? (
 | 
			
		||||
                {!loadNewerEventsIsFetching && !nextEventIsFetching ? (
 | 
			
		||||
                  <Button
 | 
			
		||||
                    onClick={() => {
 | 
			
		||||
                      loadNewerEvents();
 | 
			
		||||
                      nextEventRefetch();
 | 
			
		||||
                      loadNewesEventHandler();
 | 
			
		||||
                    }}
 | 
			
		||||
                    variant="outline"
 | 
			
		||||
                    colorScheme="suggested"
 | 
			
		||||
| 
						 | 
				
			
			@ -445,23 +441,31 @@ const EntriesNavigation = () => {
 | 
			
		|||
                  ></Button>
 | 
			
		||||
                )}
 | 
			
		||||
              </Stack>
 | 
			
		||||
              {entries.map((entry, idx) => (
 | 
			
		||||
                <StreamEntry
 | 
			
		||||
                  showOnboardingTooltips={false}
 | 
			
		||||
                  key={`entry-list-${idx}`}
 | 
			
		||||
                  entry={entry}
 | 
			
		||||
                  disableDelete={!canDelete}
 | 
			
		||||
                  disableCopy={!canCreate}
 | 
			
		||||
                  filterCallback={handleFilterStateCallback}
 | 
			
		||||
                  filterConstants={{ DIRECTIONS, CONDITION, FILTER_TYPES }}
 | 
			
		||||
                />
 | 
			
		||||
              ))}
 | 
			
		||||
              {previousEvent && !eventsIsFetching ? (
 | 
			
		||||
              {streamCache
 | 
			
		||||
                .slice(
 | 
			
		||||
                  cursor,
 | 
			
		||||
                  streamCache.length <= cursor + PAGE_SIZE
 | 
			
		||||
                    ? streamCache.length
 | 
			
		||||
                    : cursor + PAGE_SIZE
 | 
			
		||||
                )
 | 
			
		||||
                .map((entry, idx) => (
 | 
			
		||||
                  <StreamEntry
 | 
			
		||||
                    showOnboardingTooltips={false}
 | 
			
		||||
                    key={`entry-list-${idx}`}
 | 
			
		||||
                    entry={entry}
 | 
			
		||||
                    disableDelete={!canDelete}
 | 
			
		||||
                    disableCopy={!canCreate}
 | 
			
		||||
                    filterCallback={handleFilterStateCallback}
 | 
			
		||||
                    filterConstants={{ DIRECTIONS, CONDITION, FILTER_TYPES }}
 | 
			
		||||
                  />
 | 
			
		||||
                ))}
 | 
			
		||||
              {previousEvent &&
 | 
			
		||||
              !loadOlderEventsIsFetching &&
 | 
			
		||||
              !previousEventIsFetching ? (
 | 
			
		||||
                <Center>
 | 
			
		||||
                  <Button
 | 
			
		||||
                    onClick={() => {
 | 
			
		||||
                      loadOlderEvents();
 | 
			
		||||
                      previousEventRefetch();
 | 
			
		||||
                      loadPreviousEventHandler();
 | 
			
		||||
                    }}
 | 
			
		||||
                    variant="outline"
 | 
			
		||||
                    colorScheme="suggested"
 | 
			
		||||
| 
						 | 
				
			
			@ -471,7 +475,7 @@ const EntriesNavigation = () => {
 | 
			
		|||
                </Center>
 | 
			
		||||
              ) : (
 | 
			
		||||
                <Center>
 | 
			
		||||
                  {!eventsIsFetching ? (
 | 
			
		||||
                  {!previousEventIsFetching && !loadOlderEventsIsFetching ? (
 | 
			
		||||
                    "Тransactions not found. You can subscribe to more addresses in Subscriptions menu."
 | 
			
		||||
                  ) : (
 | 
			
		||||
                    <Button
 | 
			
		||||
| 
						 | 
				
			
			@ -483,21 +487,6 @@ const EntriesNavigation = () => {
 | 
			
		|||
                  )}
 | 
			
		||||
                </Center>
 | 
			
		||||
              )}
 | 
			
		||||
              {streamBoundary.previous_event_time && eventsIsLoading ? (
 | 
			
		||||
                <Center>
 | 
			
		||||
                  <Spinner
 | 
			
		||||
                    //hidden={!isFetchingMore}
 | 
			
		||||
                    ref={loadMoreButtonRef}
 | 
			
		||||
                    my={8}
 | 
			
		||||
                    size="lg"
 | 
			
		||||
                    color="primary.500"
 | 
			
		||||
                    thickness="4px"
 | 
			
		||||
                    speed="1.5s"
 | 
			
		||||
                  />
 | 
			
		||||
                </Center>
 | 
			
		||||
              ) : (
 | 
			
		||||
                ""
 | 
			
		||||
              )}
 | 
			
		||||
            </Flex>
 | 
			
		||||
          </Flex>
 | 
			
		||||
        </>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ import CustomIcon from "../CustomIcon";
 | 
			
		|||
import styles from "./styles";
 | 
			
		||||
 | 
			
		||||
const Modal = ({ children, onClose }) => (
 | 
			
		||||
  <Flex onClick={onClose} css={styles.modal}>
 | 
			
		||||
  <Flex onClick={onClose} css={styles.modal} zIndex={100002}>
 | 
			
		||||
    <Flex onClick={(e) => e.stopPropagation()} css={styles.flex}>
 | 
			
		||||
      <Image
 | 
			
		||||
        color="primary.900"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,6 @@ const styles = {
 | 
			
		|||
    display: flex;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    top: 0;
 | 
			
		||||
    z-index: 100;
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    background: rgba(0, 0, 0, 0.5);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
import React, { useEffect, useState } from "react";
 | 
			
		||||
import React, { Fragment, useEffect, useState } from "react";
 | 
			
		||||
import {
 | 
			
		||||
  Text,
 | 
			
		||||
  Stack,
 | 
			
		||||
| 
						 | 
				
			
			@ -175,9 +175,9 @@ const EthereumWhalewatchCard_ = ({
 | 
			
		|||
        >
 | 
			
		||||
          Value
 | 
			
		||||
        </Text>
 | 
			
		||||
        {Object.keys(whales).map((whaleType) => {
 | 
			
		||||
        {Object.keys(whales).map((whaleType, idx) => {
 | 
			
		||||
          return (
 | 
			
		||||
            <>
 | 
			
		||||
            <Fragment key={`whale-whatch-${idx}`}>
 | 
			
		||||
              <Box gridColumn="1 / 3">
 | 
			
		||||
                <Text
 | 
			
		||||
                  h="100%"
 | 
			
		||||
| 
						 | 
				
			
			@ -238,7 +238,7 @@ const EthereumWhalewatchCard_ = ({
 | 
			
		|||
              >
 | 
			
		||||
                {whales[whaleType].statistic}
 | 
			
		||||
              </Box>
 | 
			
		||||
            </>
 | 
			
		||||
            </Fragment>
 | 
			
		||||
          );
 | 
			
		||||
        })}
 | 
			
		||||
      </SimpleGrid>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,6 +33,8 @@ export const USER_NAV_PATHES = [
 | 
			
		|||
  },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export const PAGE_SIZE = 20;
 | 
			
		||||
 | 
			
		||||
export const AWS_ASSETS_PATH = `https://s3.amazonaws.com/static.simiotics.com/moonstream/assets`;
 | 
			
		||||
export const WHITE_LOGO_W_TEXT_URL = `https://s3.amazonaws.com/static.simiotics.com/moonstream/assets/moon-logo%2Btext-white.svg`;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,7 @@
 | 
			
		|||
import { useContext } from "react";
 | 
			
		||||
import { useMutation } from "react-query";
 | 
			
		||||
import { useToast, useUser, useInviteAccept } from ".";
 | 
			
		||||
import UIContext from "../providers/UIProvider/context";
 | 
			
		||||
import { AuthService } from "../services";
 | 
			
		||||
 | 
			
		||||
const LOGIN_TYPES = {
 | 
			
		||||
| 
						 | 
				
			
			@ -7,6 +9,7 @@ const LOGIN_TYPES = {
 | 
			
		|||
  TOKEN: true,
 | 
			
		||||
};
 | 
			
		||||
const useLogin = (loginType) => {
 | 
			
		||||
  const { setLoggingIn } = useContext(UIContext);
 | 
			
		||||
  const { getUser } = useUser();
 | 
			
		||||
  const toast = useToast();
 | 
			
		||||
  const { inviteAccept } = useInviteAccept();
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +19,9 @@ const useLogin = (loginType) => {
 | 
			
		|||
    error,
 | 
			
		||||
    data,
 | 
			
		||||
  } = useMutation(AuthService.login, {
 | 
			
		||||
    onMutate: () => {
 | 
			
		||||
      setLoggingIn(true);
 | 
			
		||||
    },
 | 
			
		||||
    onSuccess: (data) => {
 | 
			
		||||
      // Default value for loginType is LOGIN_TYPES.MANUAL
 | 
			
		||||
      if (!loginType) {
 | 
			
		||||
| 
						 | 
				
			
			@ -37,6 +43,9 @@ const useLogin = (loginType) => {
 | 
			
		|||
    onError: (error) => {
 | 
			
		||||
      toast(error, "error");
 | 
			
		||||
    },
 | 
			
		||||
    onSettled: () => {
 | 
			
		||||
      setLoggingIn(false);
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
import { useCallback, useContext } from "react";
 | 
			
		||||
import { useContext } from "react";
 | 
			
		||||
import { useMutation, useQueryClient } from "react-query";
 | 
			
		||||
import { useUser, useRouter } from ".";
 | 
			
		||||
import UIContext from "../providers/UIProvider/context";
 | 
			
		||||
| 
						 | 
				
			
			@ -7,21 +7,19 @@ import { AuthService } from "../services";
 | 
			
		|||
const useLogout = () => {
 | 
			
		||||
  const { setLoggingOut } = useContext(UIContext);
 | 
			
		||||
  const router = useRouter();
 | 
			
		||||
  const { mutate: revoke } = useMutation(AuthService.revoke, {
 | 
			
		||||
  const cache = useQueryClient();
 | 
			
		||||
  const { mutate: logout } = useMutation(AuthService.revoke, {
 | 
			
		||||
    onMutate: () => {
 | 
			
		||||
      setLoggingOut(true);
 | 
			
		||||
    },
 | 
			
		||||
    onSuccess: () => {
 | 
			
		||||
      router.push("/");
 | 
			
		||||
      setUser(null);
 | 
			
		||||
      localStorage.removeItem("MOONSTREAM_ACCESS_TOKEN");
 | 
			
		||||
      cache.clear();
 | 
			
		||||
      setUser(null);
 | 
			
		||||
      router.push("/");
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
  const { setUser } = useUser();
 | 
			
		||||
  const cache = useQueryClient();
 | 
			
		||||
 | 
			
		||||
  const logout = useCallback(() => {
 | 
			
		||||
    setLoggingOut(true);
 | 
			
		||||
    revoke();
 | 
			
		||||
  }, [revoke, setLoggingOut]);
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    logout,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,9 @@ const useSignUp = (source) => {
 | 
			
		|||
    data,
 | 
			
		||||
    isSuccess,
 | 
			
		||||
  } = useMutation(AuthService.register(), {
 | 
			
		||||
    onMutate: () => {
 | 
			
		||||
      ui.setLoggingIn(true);
 | 
			
		||||
    },
 | 
			
		||||
    onSuccess: (response) => {
 | 
			
		||||
      localStorage.setItem("MOONSTREAM_ACCESS_TOKEN", response.data.id);
 | 
			
		||||
      const invite_code = window.sessionStorage.getItem("invite_code");
 | 
			
		||||
| 
						 | 
				
			
			@ -35,13 +38,15 @@ const useSignUp = (source) => {
 | 
			
		|||
        });
 | 
			
		||||
      }
 | 
			
		||||
      getUser();
 | 
			
		||||
      ui.setisOnboardingComplete(false);
 | 
			
		||||
      ui.setOnboardingState({ welcome: 0, subscriptions: 0, stream: 0 });
 | 
			
		||||
      ui.setOnboardingComplete(false);
 | 
			
		||||
      router.push("/welcome", undefined, { shallow: false });
 | 
			
		||||
    },
 | 
			
		||||
    onError: (error) => {
 | 
			
		||||
      toast(error, "error");
 | 
			
		||||
    },
 | 
			
		||||
    onSettled: () => {
 | 
			
		||||
      ui.setLoggingIn(false);
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,17 +1,18 @@
 | 
			
		|||
import { useState } from "react";
 | 
			
		||||
 | 
			
		||||
import { StreamService } from "../services";
 | 
			
		||||
import { useQuery } from "react-query";
 | 
			
		||||
import { queryCacheProps } from "./hookCommon";
 | 
			
		||||
import { defaultStreamBoundary } from "../services/servertime.service.js";
 | 
			
		||||
 | 
			
		||||
const useStream = (q) => {
 | 
			
		||||
import { PAGE_SIZE } from "../constants";
 | 
			
		||||
const useStream = (q, streamCache, setStreamCache, cursor, setCursor) => {
 | 
			
		||||
  const [streamQuery, setStreamQuery] = useState(q || "");
 | 
			
		||||
  const [events, setEvents] = useState([]);
 | 
			
		||||
  const [streamBoundary, setStreamBoundary] = useState({});
 | 
			
		||||
  const [olderEvent, setOlderEvent] = useState(null);
 | 
			
		||||
  const [newerEvent, setNewerEvent] = useState(null);
 | 
			
		||||
 | 
			
		||||
  const twentyFourHoursInMs = 1000 * 60 * 60 * 24;
 | 
			
		||||
 | 
			
		||||
  const isStreamBoundaryEmpty = () => {
 | 
			
		||||
    return !streamBoundary.start_time && !streamBoundary.end_time;
 | 
			
		||||
  };
 | 
			
		||||
| 
						 | 
				
			
			@ -30,15 +31,6 @@ const useStream = (q) => {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    let newBoundary = { ...streamBoundary };
 | 
			
		||||
    // We do not check if there is no overlap between the streamBoundary and the pageBoundary - we assume
 | 
			
		||||
    // that there *is* an overlap and even if there isn't the stream should gracefully respect the
 | 
			
		||||
    // pageBoundary because that was the most recent request the user made.
 | 
			
		||||
    // TODO(zomglings): If there is no overlap in boundaries, replace streamBoundary with pageBoundary.
 | 
			
		||||
    // No overlap logic:
 | 
			
		||||
    // if (<no overlap>) {
 | 
			
		||||
    //   setStreamBoundary(pageBoundary)
 | 
			
		||||
    //   return pageBoundary
 | 
			
		||||
    // }
 | 
			
		||||
    if (!ignoreStart) {
 | 
			
		||||
      if (
 | 
			
		||||
        !newBoundary.start_time ||
 | 
			
		||||
| 
						 | 
				
			
			@ -84,13 +76,17 @@ const useStream = (q) => {
 | 
			
		|||
    return response.data;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  //////////////////////////////////////////////////
 | 
			
		||||
  /// Just load event by current event boundary ///
 | 
			
		||||
  ////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
  const {
 | 
			
		||||
    isLoading: eventsIsLoading,
 | 
			
		||||
    refetch: eventsRefetch,
 | 
			
		||||
    isFetching: eventsIsFetching,
 | 
			
		||||
    remove: eventsRemove,
 | 
			
		||||
  } = useQuery(
 | 
			
		||||
    ["stream-events", streamQuery],
 | 
			
		||||
    "stream-default",
 | 
			
		||||
    () => {
 | 
			
		||||
      if (isStreamBoundaryEmpty()) {
 | 
			
		||||
        return null;
 | 
			
		||||
| 
						 | 
				
			
			@ -102,16 +98,29 @@ const useStream = (q) => {
 | 
			
		|||
      retry: 2,
 | 
			
		||||
      onSuccess: (newEvents) => {
 | 
			
		||||
        if (newEvents && newEvents.stream_boundary && newEvents.events) {
 | 
			
		||||
          setEvents([...newEvents.events]);
 | 
			
		||||
          if (cursor === null) {
 | 
			
		||||
            setCursor(0);
 | 
			
		||||
            setStreamCache([...newEvents.events]);
 | 
			
		||||
            if (newEvents.events.length > PAGE_SIZE) {
 | 
			
		||||
              setEvents(newEvents.events.slice(0, PAGE_SIZE));
 | 
			
		||||
            } else {
 | 
			
		||||
              setEvents(newEvents.events.slice(0, newEvents.events.length));
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          updateStreamBoundaryWith(newEvents.stream_boundary, {});
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    }
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////
 | 
			
		||||
  /// Load olders events ///
 | 
			
		||||
  /////////////////////////
 | 
			
		||||
 | 
			
		||||
  const { refetch: loadOlderEvents, isFetching: loadOlderEventsIsFetching } =
 | 
			
		||||
    useQuery(
 | 
			
		||||
      ["stream-events", streamQuery],
 | 
			
		||||
      "stream-older-events",
 | 
			
		||||
      () => {
 | 
			
		||||
        if (olderEvent) {
 | 
			
		||||
          const newStreamBoundary = {
 | 
			
		||||
| 
						 | 
				
			
			@ -129,10 +138,17 @@ const useStream = (q) => {
 | 
			
		|||
      {
 | 
			
		||||
        ...queryCacheProps,
 | 
			
		||||
        enabled: false,
 | 
			
		||||
        refetchOnWindowFocus: false,
 | 
			
		||||
        refetchOnmount: false,
 | 
			
		||||
        refetchOnReconnect: false,
 | 
			
		||||
        staleTime: twentyFourHoursInMs,
 | 
			
		||||
        retry: 2,
 | 
			
		||||
        onSuccess: (newEvents) => {
 | 
			
		||||
          if (newEvents && newEvents.stream_boundary && newEvents.events) {
 | 
			
		||||
            setEvents([...newEvents.events, ...events]);
 | 
			
		||||
            let oldEventsList = streamCache;
 | 
			
		||||
 | 
			
		||||
            setStreamCache([...oldEventsList, ...newEvents.events]);
 | 
			
		||||
 | 
			
		||||
            updateStreamBoundaryWith(newEvents.stream_boundary, {
 | 
			
		||||
              ignoreEnd: true,
 | 
			
		||||
            });
 | 
			
		||||
| 
						 | 
				
			
			@ -141,9 +157,13 @@ const useStream = (q) => {
 | 
			
		|||
      }
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////
 | 
			
		||||
  /// Load newest events ///
 | 
			
		||||
  /////////////////////////
 | 
			
		||||
 | 
			
		||||
  const { refetch: loadNewerEvents, isFetching: loadNewerEventsIsFetching } =
 | 
			
		||||
    useQuery(
 | 
			
		||||
      ["stream-events", streamQuery],
 | 
			
		||||
      "stream-newest-events",
 | 
			
		||||
      () => {
 | 
			
		||||
        if (newerEvent) {
 | 
			
		||||
          const newStreamBoundary = {
 | 
			
		||||
| 
						 | 
				
			
			@ -155,16 +175,28 @@ const useStream = (q) => {
 | 
			
		|||
            end_time: newerEvent.event_timestamp + 5 * 60,
 | 
			
		||||
            include_end: true,
 | 
			
		||||
          };
 | 
			
		||||
 | 
			
		||||
          return getEvents(newStreamBoundary);
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        ...queryCacheProps,
 | 
			
		||||
        enabled: false,
 | 
			
		||||
        refetchOnWindowFocus: false,
 | 
			
		||||
        refetchOnmount: false,
 | 
			
		||||
        refetchOnReconnect: false,
 | 
			
		||||
        retry: 2,
 | 
			
		||||
        staleTime: twentyFourHoursInMs,
 | 
			
		||||
        onSuccess: (newEvents) => {
 | 
			
		||||
          if (newEvents && newEvents.stream_boundary && newEvents.events) {
 | 
			
		||||
            setEvents([...events, ...newEvents.events]);
 | 
			
		||||
            let oldEventsList = streamCache;
 | 
			
		||||
 | 
			
		||||
            setStreamCache([...newEvents.events, ...oldEventsList]);
 | 
			
		||||
 | 
			
		||||
            if (oldEventsList.length > 0) {
 | 
			
		||||
              setCursor(cursor + newEvents.events.length);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            updateStreamBoundaryWith(newEvents.stream_boundary, {
 | 
			
		||||
              ignoreStart: true,
 | 
			
		||||
            });
 | 
			
		||||
| 
						 | 
				
			
			@ -178,6 +210,10 @@ const useStream = (q) => {
 | 
			
		|||
    return response.data;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /////////////////////
 | 
			
		||||
  /// latest event ///
 | 
			
		||||
  ///////////////////
 | 
			
		||||
 | 
			
		||||
  const {
 | 
			
		||||
    data: latestEvents,
 | 
			
		||||
    isLoading: latestEventsIsLoading,
 | 
			
		||||
| 
						 | 
				
			
			@ -185,7 +221,7 @@ const useStream = (q) => {
 | 
			
		|||
    isFetching: latestEventsIsFetching,
 | 
			
		||||
    remove: latestEventsRemove,
 | 
			
		||||
  } = useQuery(
 | 
			
		||||
    ["stream-latest", streamQuery],
 | 
			
		||||
    "stream-latest",
 | 
			
		||||
    () => {
 | 
			
		||||
      if (isStreamBoundaryEmpty()) {
 | 
			
		||||
        return null;
 | 
			
		||||
| 
						 | 
				
			
			@ -204,10 +240,18 @@ const useStream = (q) => {
 | 
			
		|||
      q: streamQuery,
 | 
			
		||||
      ...streamBoundary,
 | 
			
		||||
    });
 | 
			
		||||
    setNewerEvent({ ...response.data });
 | 
			
		||||
    if (response.data) {
 | 
			
		||||
      setNewerEvent({ ...response.data });
 | 
			
		||||
    } else {
 | 
			
		||||
      setNewerEvent(null);
 | 
			
		||||
    }
 | 
			
		||||
    return response.data;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  ///////////////////////
 | 
			
		||||
  /// get next event ///
 | 
			
		||||
  /////////////////////
 | 
			
		||||
 | 
			
		||||
  const {
 | 
			
		||||
    data: nextEvent,
 | 
			
		||||
    isLoading: nextEventIsLoading,
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +259,7 @@ const useStream = (q) => {
 | 
			
		|||
    isFetching: nextEventIsFetching,
 | 
			
		||||
    remove: nextEventRemove,
 | 
			
		||||
  } = useQuery(
 | 
			
		||||
    ["stream-next", streamQuery],
 | 
			
		||||
    "stream-next",
 | 
			
		||||
    () => {
 | 
			
		||||
      if (isStreamBoundaryEmpty()) {
 | 
			
		||||
        return null;
 | 
			
		||||
| 
						 | 
				
			
			@ -238,6 +282,10 @@ const useStream = (q) => {
 | 
			
		|||
    return response.data;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  ///////////////////////////
 | 
			
		||||
  /// get previous event ///
 | 
			
		||||
  /////////////////////////
 | 
			
		||||
 | 
			
		||||
  const {
 | 
			
		||||
    data: previousEvent,
 | 
			
		||||
    isLoading: previousEventIsLoading,
 | 
			
		||||
| 
						 | 
				
			
			@ -245,7 +293,7 @@ const useStream = (q) => {
 | 
			
		|||
    isFetching: previousEventIsFetching,
 | 
			
		||||
    remove: previousEventRemove,
 | 
			
		||||
  } = useQuery(
 | 
			
		||||
    ["stream-previous", streamQuery],
 | 
			
		||||
    "stream-previous",
 | 
			
		||||
    () => {
 | 
			
		||||
      if (isStreamBoundaryEmpty()) {
 | 
			
		||||
        return null;
 | 
			
		||||
| 
						 | 
				
			
			@ -259,6 +307,34 @@ const useStream = (q) => {
 | 
			
		|||
    }
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  /// handle previous events
 | 
			
		||||
  const loadPreviousEventHandler = () => {
 | 
			
		||||
    if (streamCache.length > cursor + PAGE_SIZE) {
 | 
			
		||||
      setCursor(cursor + PAGE_SIZE);
 | 
			
		||||
    } else if (streamCache.length == cursor + PAGE_SIZE) {
 | 
			
		||||
      setCursor(cursor + PAGE_SIZE);
 | 
			
		||||
      loadOlderEvents();
 | 
			
		||||
      previousEventRefetch();
 | 
			
		||||
    } else {
 | 
			
		||||
      loadOlderEvents();
 | 
			
		||||
      previousEventRefetch();
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /// handle newest events
 | 
			
		||||
  const loadNewesEventHandler = () => {
 | 
			
		||||
    if (0 < cursor - PAGE_SIZE) {
 | 
			
		||||
      setCursor(cursor - PAGE_SIZE);
 | 
			
		||||
    } else if (0 == cursor - PAGE_SIZE) {
 | 
			
		||||
      setCursor(cursor - PAGE_SIZE);
 | 
			
		||||
      loadNewerEvents();
 | 
			
		||||
      nextEventRefetch();
 | 
			
		||||
    } else {
 | 
			
		||||
      loadNewerEvents();
 | 
			
		||||
      nextEventRefetch();
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    streamBoundary,
 | 
			
		||||
    setDefaultBoundary,
 | 
			
		||||
| 
						 | 
				
			
			@ -268,6 +344,7 @@ const useStream = (q) => {
 | 
			
		|||
    eventsRefetch,
 | 
			
		||||
    eventsIsFetching,
 | 
			
		||||
    eventsRemove,
 | 
			
		||||
    setEvents,
 | 
			
		||||
    setStreamQuery,
 | 
			
		||||
    latestEvents,
 | 
			
		||||
    latestEventsIsLoading,
 | 
			
		||||
| 
						 | 
				
			
			@ -288,6 +365,8 @@ const useStream = (q) => {
 | 
			
		|||
    loadOlderEventsIsFetching,
 | 
			
		||||
    loadNewerEvents,
 | 
			
		||||
    loadNewerEventsIsFetching,
 | 
			
		||||
    loadPreviousEventHandler,
 | 
			
		||||
    loadNewesEventHandler,
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
export default useStream;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,10 +10,6 @@ const useTxInfo = (wrappedEvent) => {
 | 
			
		|||
  if (wrappedEvent?.tx) {
 | 
			
		||||
    event = wrappedEvent.tx;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  console.log("TXINFO: wrappedEvent:", wrappedEvent);
 | 
			
		||||
  console.log("TXINFO: event:", event);
 | 
			
		||||
 | 
			
		||||
  let transaction = null;
 | 
			
		||||
  if (event.event_type === "ethereum_blockchain") {
 | 
			
		||||
    transaction = event.event_data;
 | 
			
		||||
| 
						 | 
				
			
			@ -25,11 +21,8 @@ const useTxInfo = (wrappedEvent) => {
 | 
			
		|||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  console.log("TXINFO: transaction:", transaction);
 | 
			
		||||
 | 
			
		||||
  const getTxInfo = async () => {
 | 
			
		||||
    const response = await TxInfoService.getTxInfo({ tx: { ...transaction } });
 | 
			
		||||
    console.log("TXINFO: response:", response);
 | 
			
		||||
    return response.data;
 | 
			
		||||
  };
 | 
			
		||||
  const { data, isLoading, isFetchedAfterMount, refetch, isError, error } =
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
import { createContext } from "react";
 | 
			
		||||
 | 
			
		||||
const DataContext = createContext();
 | 
			
		||||
 | 
			
		||||
export default DataContext;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
import React, { useState } from "react";
 | 
			
		||||
import DataContext from "./context";
 | 
			
		||||
 | 
			
		||||
const DataProvider = ({ children }) => {
 | 
			
		||||
  const [streamCache, setStreamCache] = useState([]);
 | 
			
		||||
  const [cursor, setCursor] = useState(0);
 | 
			
		||||
  return (
 | 
			
		||||
    <DataContext.Provider
 | 
			
		||||
      value={{ streamCache, setStreamCache, cursor, setCursor }}
 | 
			
		||||
    >
 | 
			
		||||
      {children}
 | 
			
		||||
    </DataContext.Provider>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default DataProvider;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +0,0 @@
 | 
			
		|||
import { createContext } from "react";
 | 
			
		||||
 | 
			
		||||
const JournalsContext = createContext();
 | 
			
		||||
 | 
			
		||||
export default JournalsContext;
 | 
			
		||||
| 
						 | 
				
			
			@ -1,48 +0,0 @@
 | 
			
		|||
// import React, { useContext, useState, useEffect } from "react";
 | 
			
		||||
// // import http from "axios";
 | 
			
		||||
// import { useToast } from "../../hooks";
 | 
			
		||||
// import JournalsContext from "./context";
 | 
			
		||||
// import UserContext from "../UserProvider/context";
 | 
			
		||||
// import { useQuery } from "react-query";
 | 
			
		||||
// import { JournalService } from "../../services";
 | 
			
		||||
 | 
			
		||||
// const JournalsProvider = ({ children }) => {
 | 
			
		||||
//   const user = useContext(UserContext);
 | 
			
		||||
//   const toast = useToast();
 | 
			
		||||
 | 
			
		||||
//   const journalsCache = useQuery("journals-list", JournalService.getAll, {
 | 
			
		||||
//     enabled: !!user,
 | 
			
		||||
//     refetchOnWindowFocus: false,
 | 
			
		||||
//     refetchOnMount: false,
 | 
			
		||||
//     refetchOnReconnect: false,
 | 
			
		||||
//     staleTime: 72000,
 | 
			
		||||
//     notifyOnStatusChange: false,
 | 
			
		||||
//     // refetchInterval: 1000,
 | 
			
		||||
//     onError: (error) => {
 | 
			
		||||
//       toast(error, "error");
 | 
			
		||||
//     },
 | 
			
		||||
//   });
 | 
			
		||||
 | 
			
		||||
//   const getPublicJournals = async (query) => {
 | 
			
		||||
//     const data = await JournalService.getPublicJournals();
 | 
			
		||||
 | 
			
		||||
//     const newPublicJournals = data.data.journals;
 | 
			
		||||
 | 
			
		||||
//     return [...newPublicJournals];
 | 
			
		||||
//   };
 | 
			
		||||
 | 
			
		||||
//   const publicJournalsCache = useQuery(["journals-public"], getPublicJournals, {
 | 
			
		||||
//     enabled: false,
 | 
			
		||||
//     onError: (error) => {
 | 
			
		||||
//       toast(error, "error");
 | 
			
		||||
//     },
 | 
			
		||||
//   });
 | 
			
		||||
 | 
			
		||||
//   return (
 | 
			
		||||
//     <JournalsContext.Provider value={{permissions: currentUserPermissions, publicJournalsCache, journalsCache }}>
 | 
			
		||||
//       {children}
 | 
			
		||||
//     </JournalsContext.Provider>
 | 
			
		||||
//   );
 | 
			
		||||
// };
 | 
			
		||||
 | 
			
		||||
// export default JournalsProvider;
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +11,6 @@ export const StripeProvider = ({ children }) => {
 | 
			
		|||
  useEffect(() => {
 | 
			
		||||
    let isMounted = true;
 | 
			
		||||
    if (isMounted) {
 | 
			
		||||
      console.log("Creating Stripe client to process payments");
 | 
			
		||||
      if (!stripePublishableKey) {
 | 
			
		||||
        console.warn(
 | 
			
		||||
          "Unable to process payments: Stripe publishable key not provided"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,10 @@
 | 
			
		|||
import React, { useState, useContext, useEffect, useCallback } from "react";
 | 
			
		||||
import React, {
 | 
			
		||||
  useState,
 | 
			
		||||
  useContext,
 | 
			
		||||
  useEffect,
 | 
			
		||||
  useCallback,
 | 
			
		||||
  useLayoutEffect,
 | 
			
		||||
} from "react";
 | 
			
		||||
import { useBreakpointValue } from "@chakra-ui/react";
 | 
			
		||||
import { useStorage, useQuery, useRouter } from "../../hooks";
 | 
			
		||||
import UIContext from "./context";
 | 
			
		||||
| 
						 | 
				
			
			@ -47,15 +53,25 @@ const UIProvider = ({ children }) => {
 | 
			
		|||
  // ******* APP state ********
 | 
			
		||||
  const [isLoggedIn, setLoggedIn] = useState(user && user.username);
 | 
			
		||||
  const [isLoggingOut, setLoggingOut] = useState(false);
 | 
			
		||||
  const [isLoggingIn, setLoggingIn] = useState(false);
 | 
			
		||||
  const [isAppReady, setAppReady] = useState(false);
 | 
			
		||||
  const [isAppView, setAppView] = useState(false);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (isAppView && isAppReady && !user?.username && !isLoggingOut) {
 | 
			
		||||
      // toggleModal("login");
 | 
			
		||||
  useLayoutEffect(() => {
 | 
			
		||||
    if (
 | 
			
		||||
      isAppView &&
 | 
			
		||||
      isInit &&
 | 
			
		||||
      !user?.username &&
 | 
			
		||||
      !isLoggingOut &&
 | 
			
		||||
      !isLoggingIn &&
 | 
			
		||||
      !modal
 | 
			
		||||
    ) {
 | 
			
		||||
      toggleModal("login");
 | 
			
		||||
    } else if (user || isLoggingOut) {
 | 
			
		||||
      toggleModal(false);
 | 
			
		||||
    }
 | 
			
		||||
    // eslint-disable-next-line react-hooks/exhaustive-deps
 | 
			
		||||
  }, [isAppView, isAppReady, user, isLoggingOut]);
 | 
			
		||||
  }, [isAppView, isAppReady, user, isLoggingOut, modal]);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (isLoggingOut && !isAppView && user) {
 | 
			
		||||
| 
						 | 
				
			
			@ -71,6 +87,17 @@ const UIProvider = ({ children }) => {
 | 
			
		|||
    }
 | 
			
		||||
  }, [user]);
 | 
			
		||||
 | 
			
		||||
  useLayoutEffect(() => {
 | 
			
		||||
    if (
 | 
			
		||||
      isLoggingOut &&
 | 
			
		||||
      router.nextRouter.pathname === "/" &&
 | 
			
		||||
      !user &&
 | 
			
		||||
      !localStorage.getItem("MOONSTREAM_ACCESS_TOKEN")
 | 
			
		||||
    ) {
 | 
			
		||||
      setLoggingOut(false);
 | 
			
		||||
    }
 | 
			
		||||
  }, [isLoggingOut, router.nextRouter.pathname, user]);
 | 
			
		||||
 | 
			
		||||
  // *********** Sidebar states **********************
 | 
			
		||||
 | 
			
		||||
  // Whether sidebar should be visible at all or hidden
 | 
			
		||||
| 
						 | 
				
			
			@ -150,6 +177,8 @@ const UIProvider = ({ children }) => {
 | 
			
		|||
  const [onboardingState, setOnboardingState] = useState(false);
 | 
			
		||||
  const [onboardingStep, setOnboardingStep] = useState();
 | 
			
		||||
  const [onboardingStateInit, setOnboardingStateInit] = useState(false);
 | 
			
		||||
  const [onboardingRedirectCheckPassed, setOnboardingRedirectCheckPassed] =
 | 
			
		||||
    useState(false);
 | 
			
		||||
 | 
			
		||||
  const setOnboardingComplete = useCallback(
 | 
			
		||||
    (newState) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -162,7 +191,7 @@ const UIProvider = ({ children }) => {
 | 
			
		|||
    //If onboarding state not exists - fetch it from backend
 | 
			
		||||
    //If it exists but init is not set - set init true
 | 
			
		||||
    //If it exists and is init -> post update to backend
 | 
			
		||||
    if (!onboardingState && user) {
 | 
			
		||||
    if (!onboardingState && user && !isLoggingOut) {
 | 
			
		||||
      const currentOnboardingState = async () =>
 | 
			
		||||
        PreferencesService.getOnboardingState().then((response) => {
 | 
			
		||||
          return response.data;
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +202,7 @@ const UIProvider = ({ children }) => {
 | 
			
		|||
      });
 | 
			
		||||
    } else if (user && onboardingState && !onboardingStateInit) {
 | 
			
		||||
      setOnboardingStateInit(true);
 | 
			
		||||
    } else if (onboardingStateInit) {
 | 
			
		||||
    } else if (user && onboardingStateInit) {
 | 
			
		||||
      PreferencesService.setOnboardingState(onboardingState);
 | 
			
		||||
    }
 | 
			
		||||
    // eslint-disable-next-line
 | 
			
		||||
| 
						 | 
				
			
			@ -195,16 +224,16 @@ const UIProvider = ({ children }) => {
 | 
			
		|||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    //redirect to welcome page if yet not completed onboarding
 | 
			
		||||
    if (
 | 
			
		||||
      isLoggedIn &&
 | 
			
		||||
      isAppReady &&
 | 
			
		||||
      onboardingState &&
 | 
			
		||||
      !onboardingState?.is_complete
 | 
			
		||||
    ) {
 | 
			
		||||
      router.replace("/welcome");
 | 
			
		||||
    if (isLoggedIn && onboardingState && !onboardingState?.is_complete) {
 | 
			
		||||
      router.replace("/welcome", undefined, { shallow: true });
 | 
			
		||||
    }
 | 
			
		||||
    if (isLoggedIn) {
 | 
			
		||||
      setOnboardingRedirectCheckPassed(true);
 | 
			
		||||
    } else {
 | 
			
		||||
      setOnboardingRedirectCheckPassed(false);
 | 
			
		||||
    }
 | 
			
		||||
    // eslint-disable-next-line
 | 
			
		||||
  }, [isLoggedIn, onboardingState?.is_complete, isAppReady]);
 | 
			
		||||
  }, [isLoggedIn, onboardingState?.is_complete]);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    //This will set up onboarding complete once user finishes each view at least once
 | 
			
		||||
| 
						 | 
				
			
			@ -226,7 +255,7 @@ const UIProvider = ({ children }) => {
 | 
			
		|||
      isAppReady &&
 | 
			
		||||
      user &&
 | 
			
		||||
      Number.isInteger(onboardingStep) &&
 | 
			
		||||
      onboardingState
 | 
			
		||||
      onboardingState?.steps
 | 
			
		||||
    ) {
 | 
			
		||||
      setOnboardingState({
 | 
			
		||||
        ...onboardingState,
 | 
			
		||||
| 
						 | 
				
			
			@ -243,12 +272,26 @@ const UIProvider = ({ children }) => {
 | 
			
		|||
  // ********************************************************
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (isInit && router.nextRouter.isReady && onboardingState) {
 | 
			
		||||
    if (
 | 
			
		||||
      isInit &&
 | 
			
		||||
      router.nextRouter.isReady &&
 | 
			
		||||
      onboardingState &&
 | 
			
		||||
      !isLoggingOut &&
 | 
			
		||||
      !isLoggingIn &&
 | 
			
		||||
      onboardingRedirectCheckPassed
 | 
			
		||||
    ) {
 | 
			
		||||
      setAppReady(true);
 | 
			
		||||
    } else {
 | 
			
		||||
      setAppReady(false);
 | 
			
		||||
    }
 | 
			
		||||
  }, [isInit, router, onboardingState]);
 | 
			
		||||
  }, [
 | 
			
		||||
    isInit,
 | 
			
		||||
    router,
 | 
			
		||||
    onboardingState,
 | 
			
		||||
    isLoggingOut,
 | 
			
		||||
    isLoggingIn,
 | 
			
		||||
    onboardingRedirectCheckPassed,
 | 
			
		||||
  ]);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <UIContext.Provider
 | 
			
		||||
| 
						 | 
				
			
			@ -284,6 +327,8 @@ const UIProvider = ({ children }) => {
 | 
			
		|||
        setOnboardingState,
 | 
			
		||||
        onboardingState,
 | 
			
		||||
        isLoggingOut,
 | 
			
		||||
        isLoggingIn,
 | 
			
		||||
        setLoggingIn,
 | 
			
		||||
      }}
 | 
			
		||||
    >
 | 
			
		||||
      {children}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
export { default as AnalyticsProvider } from "./AnalyticsProvider";
 | 
			
		||||
export { default as JournalsProvider } from "./JournalsProvider";
 | 
			
		||||
export { default as JournalsProvider } from "./DataProvider";
 | 
			
		||||
export { default as ModalProvider } from "./ModalProvider";
 | 
			
		||||
export { default as StripeProvider } from "./StripeProvider";
 | 
			
		||||
export { default as UserProvider } from "./UserProvider";
 | 
			
		||||
export { default as UIProvider } from "./UIProvider";
 | 
			
		||||
export { default as DataProvider } from "./DataProvider";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,20 +1,18 @@
 | 
			
		|||
import { Flex } from "@chakra-ui/react";
 | 
			
		||||
import { Flex, Spinner, Box } from "@chakra-ui/react";
 | 
			
		||||
import { getLayout as getSiteLayout } from "./RootLayout";
 | 
			
		||||
import React, { useContext, useLayoutEffect } from "react";
 | 
			
		||||
import React, { useContext, useEffect } from "react";
 | 
			
		||||
import UIContext from "../core/providers/UIProvider/context";
 | 
			
		||||
 | 
			
		||||
const AppLayout = ({ children }) => {
 | 
			
		||||
  const ui = useContext(UIContext);
 | 
			
		||||
 | 
			
		||||
  useLayoutEffect(() => {
 | 
			
		||||
    if (ui.isAppReady) {
 | 
			
		||||
      ui.setAppView(true);
 | 
			
		||||
      return () => {
 | 
			
		||||
        ui.setAppView(false);
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
    //eslint-disable-next-line
 | 
			
		||||
  }, [ui.isAppReady]);
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    ui.setAppView(true);
 | 
			
		||||
    return () => {
 | 
			
		||||
      ui.setAppView(false);
 | 
			
		||||
    };
 | 
			
		||||
    // eslint-disable-next-line
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Flex
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +23,28 @@ const AppLayout = ({ children }) => {
 | 
			
		|||
      w="100%"
 | 
			
		||||
      overflow="hidden"
 | 
			
		||||
    >
 | 
			
		||||
      {(!ui.isAppReady || !ui.isLoggedIn) && (
 | 
			
		||||
        <Spinner
 | 
			
		||||
          position="absolute"
 | 
			
		||||
          top="50%"
 | 
			
		||||
          left="50%"
 | 
			
		||||
          size="xl"
 | 
			
		||||
          speed="1s"
 | 
			
		||||
          zIndex={100001}
 | 
			
		||||
        />
 | 
			
		||||
      )}
 | 
			
		||||
      {(!ui.isAppReady || !ui.isLoggedIn) && (
 | 
			
		||||
        <Box
 | 
			
		||||
          position="absolute"
 | 
			
		||||
          top="0"
 | 
			
		||||
          bottom={0}
 | 
			
		||||
          left={0}
 | 
			
		||||
          right={0}
 | 
			
		||||
          bg="rgba(0,0,0,0.7)"
 | 
			
		||||
          zIndex={100000}
 | 
			
		||||
        />
 | 
			
		||||
      )}
 | 
			
		||||
 | 
			
		||||
      {ui.isAppReady && ui.isLoggedIn && children}
 | 
			
		||||
    </Flex>
 | 
			
		||||
  );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,32 +1,14 @@
 | 
			
		|||
import { CloseIcon } from "@chakra-ui/icons";
 | 
			
		||||
import {
 | 
			
		||||
  Flex,
 | 
			
		||||
  Spinner,
 | 
			
		||||
  Center,
 | 
			
		||||
  Text,
 | 
			
		||||
  Link,
 | 
			
		||||
  IconButton,
 | 
			
		||||
} from "@chakra-ui/react";
 | 
			
		||||
import React, { Suspense, useContext, useState, useEffect } from "react";
 | 
			
		||||
import { Flex, Center, Text, Link, IconButton } from "@chakra-ui/react";
 | 
			
		||||
import React, { Suspense, useContext, useState } from "react";
 | 
			
		||||
import UIContext from "../core/providers/UIProvider/context";
 | 
			
		||||
const Sidebar = React.lazy(() => import("../components/Sidebar"));
 | 
			
		||||
const Navbar = React.lazy(() => import("../components/Navbar"));
 | 
			
		||||
import UIContext from "../core/providers/UIProvider/context";
 | 
			
		||||
 | 
			
		||||
const RootLayout = (props) => {
 | 
			
		||||
  const ui = useContext(UIContext);
 | 
			
		||||
  const [showSpinner, setSpinner] = useState(true);
 | 
			
		||||
  const [showBanner, setShowBanner] = useState(true);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (ui.isAppView && ui.isAppReady) {
 | 
			
		||||
      setSpinner(false);
 | 
			
		||||
    } else if (!ui.isAppView) {
 | 
			
		||||
      setSpinner(false);
 | 
			
		||||
    } else {
 | 
			
		||||
      setSpinner(true);
 | 
			
		||||
    }
 | 
			
		||||
  }, [ui, setSpinner]);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Flex
 | 
			
		||||
      direction="row"
 | 
			
		||||
| 
						 | 
				
			
			@ -98,8 +80,7 @@ const RootLayout = (props) => {
 | 
			
		|||
            </Flex>
 | 
			
		||||
          </Flex>
 | 
			
		||||
        )}
 | 
			
		||||
        {!showSpinner && props.children}
 | 
			
		||||
        {showSpinner && <Spinner />}
 | 
			
		||||
        {props.children}
 | 
			
		||||
      </Flex>
 | 
			
		||||
    </Flex>
 | 
			
		||||
  );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue