From b102f4eeb6823923bb7dd1693e8ea8aefe5c9186 Mon Sep 17 00:00:00 2001 From: Tim Pechersky Date: Fri, 13 Aug 2021 13:01:38 +0200 Subject: [PATCH 1/3] cards and stream layout improvements --- frontend/pages/stream/index.js | 45 ++++- frontend/src/components/AppNavbar.js | 42 +---- frontend/src/components/EntriesNavigation.js | 32 +--- .../components/SteamEntryDetails.js} | 67 ++------ frontend/src/components/StreamEntry.js | 162 +++++++++--------- frontend/src/core/hooks/useStream.js | 5 +- .../src/core/providers/UIProvider/index.js | 31 ++-- frontend/src/layouts/EntriesLayout.js | 7 +- frontend/styles/styles.css | 8 +- 9 files changed, 171 insertions(+), 228 deletions(-) rename frontend/{pages/stream/[entryId].js => src/components/SteamEntryDetails.js} (53%) diff --git a/frontend/pages/stream/index.js b/frontend/pages/stream/index.js index 5c11e593..06921ccf 100644 --- a/frontend/pages/stream/index.js +++ b/frontend/pages/stream/index.js @@ -1,6 +1,49 @@ +import React, { useContext } from "react"; import { getLayout } from "../../src/layouts/EntriesLayout"; +import StreamEntryDetails from "../../src/components/SteamEntryDetails"; +import UIContext from "../../src/core/providers/UIProvider/context"; +import { + Box, + Heading, + Text, + Stack, + UnorderedList, + ListItem, +} from "@chakra-ui/react"; const Entry = () => { - return ""; + const ui = useContext(UIContext); + + // return ""; + if (ui.currentTransaction) { + return ; + } else + return ( + + <> + + Stream view + + In this view you can follow events that happen on your subscribed + addresses + + + + Click filter icon on right top corner to filter by specific + address across your subscriptions + + + On event cards you can click at right corner to see detailed + view! + + + For any adress of interest here you can copy it and subscribe at + subscription screen + + + + + + ); }; Entry.getLayout = getLayout; export default Entry; diff --git a/frontend/src/components/AppNavbar.js b/frontend/src/components/AppNavbar.js index 0a26b7fd..10ff2a41 100644 --- a/frontend/src/components/AppNavbar.js +++ b/frontend/src/components/AppNavbar.js @@ -2,7 +2,6 @@ import React, { useState, useContext, useEffect } from "react"; import RouterLink from "next/link"; import { Flex, - Button, Image, Text, IconButton, @@ -16,7 +15,6 @@ import { PopoverCloseButton, useBreakpointValue, Spacer, - Fade, } from "@chakra-ui/react"; import { HamburgerIcon, @@ -95,36 +93,6 @@ const AppNavbar = () => { {!ui.isMobileView && ( <> - - - @@ -185,8 +153,9 @@ const AppNavbar = () => { aria-label="App navigation" icon={} onClick={() => { - router.params?.entryId && ui.entriesViewMode === "entry" - ? ui.setEntriesViewMode("list") + router.nextRouter.pathname === "/stream" && + ui.isEntryDetailView + ? ui.setEntryDetailView(false) : router.nextRouter.back(); }} /> @@ -216,8 +185,9 @@ const AppNavbar = () => { aria-label="App navigation" icon={} onClick={() => { - router.params?.entryId && ui.entriesViewMode === "list" - ? ui.setEntriesViewMode("entry") + router.nextRouter.pathname === "/stream" && + !ui.isEntryDetailView + ? ui.setEntryDetailView(true) : history.forward(); }} /> diff --git a/frontend/src/components/EntriesNavigation.js b/frontend/src/components/EntriesNavigation.js index f08df544..0f380ab0 100644 --- a/frontend/src/components/EntriesNavigation.js +++ b/frontend/src/components/EntriesNavigation.js @@ -32,7 +32,6 @@ import { TagCloseButton, Stack, Spacer, - useBoolean, } from "@chakra-ui/react"; import { useSubscriptions } from "../core/hooks"; import StreamEntry from "./StreamEntry"; @@ -40,9 +39,7 @@ import UIContext from "../core/providers/UIProvider/context"; import { FaFilter } from "react-icons/fa"; import useStream from "../core/hooks/useStream"; import { ImCancelCircle } from "react-icons/im"; -import { IoStopCircleOutline, IoPlayCircleOutline } from "react-icons/io5"; -const pageSize = 25; const FILTER_TYPES = { ADDRESS: 0, GAS: 1, @@ -64,7 +61,6 @@ const CONDITION = { const EntriesNavigation = () => { const ui = useContext(UIContext); - const [isStreamOn, setStreamState] = useBoolean(true); const { isOpen, onOpen, onClose } = useDisclosure(); const { subscriptionsCache } = useSubscriptions(); const [newFilterState, setNewFilterState] = useState([ @@ -150,35 +146,23 @@ const EntriesNavigation = () => { }; const { EntriesPages, isLoading, refetch, isFetching, remove } = useStream({ - refreshRate: 1500, searchQuery: ui.searchTerm, start_time: streamBoundary.start_time, end_time: streamBoundary.end_time, include_start: streamBoundary.include_start, include_end: streamBoundary.include_end, - enabled: isStreamOn, updateStreamBoundaryWith: updateStreamBoundaryWith, streamBoundary: streamBoundary, setStreamBoundary: setStreamBoundary, isContent: false, }); - // const handleScroll = ({ currentTarget }) => { - // if ( - // currentTarget.scrollTop + currentTarget.clientHeight >= - // 0.5 * currentTarget.scrollHeight - // ) { - // if (!isLoading && hasPreviousPage) { - // fetchPreviousPage(); - // } - // } - // }; useEffect(() => { if (!streamBoundary.start_time && !streamBoundary.end_time) { refetch(); } - }, [streamBoundary]); + }, [streamBoundary, refetch]); const setFilterProps = useCallback( (filterIdx, props) => { @@ -442,20 +426,6 @@ const EntriesNavigation = () => { - - setStreamState.toggle()} - icon={ - isStreamOn ? ( - - ) : ( - - ) - } - colorScheme={isStreamOn ? "unsafe" : "suggested"} - /> - {filterState.map((filter, idx) => { if (filter.type === FILTER_TYPES.DISABLED) return ""; return ( diff --git a/frontend/pages/stream/[entryId].js b/frontend/src/components/SteamEntryDetails.js similarity index 53% rename from frontend/pages/stream/[entryId].js rename to frontend/src/components/SteamEntryDetails.js index a233f5e2..8d0f46e4 100644 --- a/frontend/pages/stream/[entryId].js +++ b/frontend/src/components/SteamEntryDetails.js @@ -1,49 +1,15 @@ import React, { useContext } from "react"; -import { - Flex, - HStack, - Skeleton, - Box, - Heading, - Center, - Spinner, -} from "@chakra-ui/react"; -import { useTxInfo, useRouter } from "../../src/core/hooks"; -import FourOFour from "../../src/components/FourOFour"; -import FourOThree from "../../src/components/FourOThree"; -import Tags from "../../src/components/Tags"; -import { getLayout } from "../../src/layouts/EntriesLayout"; -import Scrollable from "../../src/components/Scrollable"; -import TxInfo from "../../src/components/TxInfo"; -import UIContext from "../../src/core/providers/UIProvider/context"; +import { Flex, HStack, Skeleton, Heading } from "@chakra-ui/react"; +import { useTxInfo } from "../core/hooks"; +import FourOFour from "./FourOFour"; +import FourOThree from "./FourOThree"; +import Tags from "./Tags"; +import Scrollable from "./Scrollable"; +import TxInfo from "./TxInfo"; +import UIContext from "../core/providers/UIProvider/context"; -const Entry = () => { +const SteamEntryDetails = () => { const ui = useContext(UIContext); - const router = useRouter(); - const { entryId } = router.params; - - const callReroute = () => { - ui.setEntriesViewMode("list"); - router.push({ - pathname: `/stream`, - query: router.query, - }); - const LoadingSpinner = () => ( - -
-
-
- ); - return ; - }; const { data: entry, @@ -54,20 +20,13 @@ const Entry = () => { error, } = useTxInfo({ tx: ui.currentTransaction }); if (!isFetching) { - return callReroute(); + return ""; } if (isError && error.response.status === 404) return ; if (isError && error.response.status === 403) return ; - // if (!entry || isLoading) return ""; return ( - + { { ); }; -Entry.getLayout = getLayout; -export default Entry; +export default SteamEntryDetails; diff --git a/frontend/src/components/StreamEntry.js b/frontend/src/components/StreamEntry.js index 52ab9284..4fa667b6 100644 --- a/frontend/src/components/StreamEntry.js +++ b/frontend/src/components/StreamEntry.js @@ -9,14 +9,18 @@ import { Heading, Image, useMediaQuery, + Spacer, + Spinner, } from "@chakra-ui/react"; import moment from "moment"; import { ArrowRightIcon } from "@chakra-ui/icons"; import { useRouter } from "../core/hooks"; import UIContext from "../core/providers/UIProvider/context"; import { useToast } from "../core/hooks"; +import { useSubscriptions } from "../core/hooks"; const StreamEntry = ({ entry }) => { + const { subscriptionsCache } = useSubscriptions(); const ui = useContext(UIContext); const router = useRouter(); const [copyString, setCopyString] = useState(false); @@ -32,16 +36,21 @@ const StreamEntry = ({ entry }) => { } }, [copyString, onCopy, hasCopied, toast]); const handleViewClicked = (entryId) => { - ui.setEntryId(entryId); - ui.setEntriesViewMode("entry"); ui.setCurrentTransaction(entry); - router.push({ - pathname: `/stream/${entry.hash}`, - query: router.query, - }); }; const [showFullView] = useMediaQuery(["(min-width: 420px)"]); + if (subscriptionsCache.isLoading) return ; + + const from_color = + subscriptionsCache.data.subscriptions.find((obj) => { + return obj.address === entry.from_address; + })?.color ?? "gray.500"; + + const to_color = + subscriptionsCache.data.subscriptions.find((obj) => { + return obj.address === entry.to_address; + })?.color ?? "gray.500"; return ( { bgColor="gray.100" borderColor="white.300" transition="0.1s" - _hover={{ bg: "secondary.200" }} flexBasis="50px" direction="row" justifySelf="center" @@ -80,9 +88,11 @@ const StreamEntry = ({ entry }) => { borderLeftRadius="md" borderColor="gray.600" spacing={0} - h="fit-content" - minH="fit-content" + h="auto" + // h="fit-content" + // minH="fit-content" overflowX="hidden" + overflowY="visible" > { textAlign="center" spacing={0} alignItems="center" - bgColor="brand.300" + bgColor="gray.300" > { "https://upload.wikimedia.org/wikipedia/commons/0/05/Ethereum_logo_2014.svg" } /> - Ethereum blockhain + + Hash + + + setCopyString(entry.hash)} + pr={12} + > + {entry.hash} + { spacing={0} > { mx={0} py="2px" fontSize="sm" - bgColor="secondary.200" + bgColor={from_color} isTruncated w="calc(100%)" h="100%" @@ -166,9 +186,8 @@ const StreamEntry = ({ entry }) => { spacing={0} > { { - - + + { {entry.gasPrice} - - + + { {entry.gas} - - + + { {entry.value} - - {entry.timestamp && ( - + + + - + Nonce: + + + setCopyString(entry.value)} + > + {entry.nonce} + + + + {entry.timestamp && ( + + {moment(entry.timestamp * 1000).format( "DD MMM, YYYY, HH:mm:ss" )}{" "} - + )} - + + )} @@ -339,7 +337,7 @@ const StreamEntry = ({ entry }) => { variant="solid" px={0} minW="24px" - colorScheme="suggested" + colorScheme="secondary" icon={} /> diff --git a/frontend/src/core/hooks/useStream.js b/frontend/src/core/hooks/useStream.js index bf589599..72090211 100644 --- a/frontend/src/core/hooks/useStream.js +++ b/frontend/src/core/hooks/useStream.js @@ -3,14 +3,12 @@ import { useQuery } from "react-query"; import { queryCacheProps } from "./hookCommon"; const useJournalEntries = ({ - refreshRate, searchQuery, start_time, end_time, include_start, include_end, updateStreamBoundaryWith, - enabled, }) => { // set our get method const getStream = @@ -47,8 +45,7 @@ const useJournalEntries = ({ // response is object which return condition in getStream // TODO(andrey): Response should send page parameters inside "boundary" object (can be null). updateStreamBoundaryWith(response.boundaries); - }, - enabled: !!enabled, + } } ); diff --git a/frontend/src/core/providers/UIProvider/index.js b/frontend/src/core/providers/UIProvider/index.js index 9beb3ada..5107a13c 100644 --- a/frontend/src/core/providers/UIProvider/index.js +++ b/frontend/src/core/providers/UIProvider/index.js @@ -30,8 +30,6 @@ const UIProvider = ({ children }) => { const { modal, toggleModal } = useContext(ModalContext); const [searchTerm, setSearchTerm] = useQuery("q", " ", true, false); - const [entryId, setEntryId] = useState(); - const [searchBarActive, setSearchBarActive] = useState(false); // ****** Session state ***** @@ -136,22 +134,30 @@ const UIProvider = ({ children }) => { // *********** Entries layout states ********************** + // + // const [entryId, setEntryId] = useState(); + // Current transaction to show in sideview + const [currentTransaction, _setCurrentTransaction] = useState(undefined); + const [isEntryDetailView, setEntryDetailView] = useState(false); + + const setCurrentTransaction = (tx) => { + _setCurrentTransaction(tx); + setEntryDetailView(!!tx); + }; + /** * States that entries list box should be expanded * Default true in mobile mode and false in desktop mode */ const [entriesViewMode, setEntriesViewMode] = useState( - router.params?.entryId ? "entry" : "list" + isMobileView ? "list" : "split" ); useEffect(() => { - setEntriesViewMode(router.params?.entryId ? "entry" : "list"); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [router.params?.id]); - - // *********** TX stream state ********************** - - const [currentTransaction, setCurrentTransaction] = useState(undefined); + setEntriesViewMode( + isMobileView ? (isEntryDetailView ? "entry" : "list") : "split" + ); + }, [isEntryDetailView, isMobileView]); // ******************************************************** @@ -175,14 +181,13 @@ const UIProvider = ({ children }) => { isLoggedIn, isAppReady, entriesViewMode, - setEntriesViewMode, + setEntryDetailView, modal, toggleModal, - entryId, - setEntryId, sessionId, currentTransaction, setCurrentTransaction, + isEntryDetailView, }} > {children} diff --git a/frontend/src/layouts/EntriesLayout.js b/frontend/src/layouts/EntriesLayout.js index 119e50ff..5a1f23b5 100644 --- a/frontend/src/layouts/EntriesLayout.js +++ b/frontend/src/layouts/EntriesLayout.js @@ -20,6 +20,7 @@ const EntriesLayout = (props) => { <> { ? { transition: "1s", width: "100%" } : ui.entriesViewMode === "entry" ? { transition: "1s", width: "0%" } - : { overflowX: "hidden", height: "100%" } + : { + overflowX: "hidden", + height: "100%", + width: ui.isMobileView ? "100%" : "55%", + } } pane2Style={ ui.entriesViewMode === "entry" diff --git a/frontend/styles/styles.css b/frontend/styles/styles.css index 80b52141..ab3e2ad8 100644 --- a/frontend/styles/styles.css +++ b/frontend/styles/styles.css @@ -46,6 +46,7 @@ } .Resizer.disabled:hover { border-color: transparent; + cursor: inherit; } .triangle { @@ -156,7 +157,7 @@ word-break: break-word; } -.mde-preview * { +.mde-preview * { word-break: break-word; } @@ -181,12 +182,10 @@ padding: 0.5rem; } - code { white-space: pre-line !important; } - .fade-in-section { opacity: 0; transform: translateY(5vh); @@ -195,8 +194,7 @@ code { will-change: opacity, visibility; } .fade-in-section.is-visible { - opacity: 1; transform: none; visibility: visible; -} \ No newline at end of file +} From 8749ec0e3329474b34ca266188c9e2b6d382df78 Mon Sep 17 00:00:00 2001 From: Tim Pechersky Date: Fri, 13 Aug 2021 13:01:53 +0200 Subject: [PATCH 2/3] clear comments and lint --- frontend/pages/subscriptions.js | 1 - frontend/src/core/hooks/useTxInfo.js | 12 ++++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/frontend/pages/subscriptions.js b/frontend/pages/subscriptions.js index 867bf8ea..5a9cbb5e 100644 --- a/frontend/pages/subscriptions.js +++ b/frontend/pages/subscriptions.js @@ -62,7 +62,6 @@ const Subscriptions = () => {