-
-
Notifications
You must be signed in to change notification settings - Fork 1
refactor: upgrade routing #171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
7821818
chore: upgrade packages
gratestas 94c6098
refactor: use new router construction with createBrowserRouter
gratestas 0068e08
refactor: move redirection logic based on chainId up to Router level
gratestas f2902b4
refactor: remove reduntan useEffect logic from all route components
gratestas 0454688
refactor: apply required changes to comply with routing updates
gratestas 17c1e03
chore: delete commented out code
gratestas a8ab74a
fix: update getAllContributors query
gratestas 436c221
refactor: implement loader router API to article route
gratestas 359dd4a
fix: navigation path to Account route
gratestas f0cf593
refactor: implement loader route API to account page
gratestas 831bd0f
refactor: apply loader route API to Browse page & reduce code complexity
gratestas 8e84876
refactor: update Account route loader
gratestas a589646
fix: use absolute path in article route link
gratestas 129b03a
fix: continuous update of blockNumber in graphMetada based on chainId
gratestas 6c4af06
refactor: apply route loader API to Court page
gratestas 23b9d44
fix: update ethersProvider when app's network is changed
gratestas f27f905
feat: add default network based on environment
gratestas 2696a42
fix: use chainId from networkMap instead of hardcoded
gratestas b598abb
refactor: remove duplicated code in Navigation component
gratestas ed1d543
fix: enable missing usage of metaEvidenceContents
gratestas f172f9c
feat: revalidate data using router API manually
gratestas acfec33
chore: remove unnecessary function declarations
gratestas c2d66ad
refactor: reduce code duplication
gratestas File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import { useContext } from "react"; | ||
| import { EthereumContext } from "../data/ethereumProvider"; | ||
| import { Navigate, Outlet } from "react-router-dom"; | ||
|
|
||
| export default function AuthRequired() { | ||
| const { accounts, chainId } = useContext(EthereumContext); | ||
| if (accounts[0] === undefined) { | ||
| return <Navigate to={chainId} replace />; | ||
| } | ||
| return <Outlet />; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| import { useContext, useEffect } from "react"; | ||
| import { Outlet, useLocation, useNavigate, useParams } from "react-router-dom"; | ||
| import { EthereumContext, networkMap } from "../data/ethereumProvider"; | ||
|
|
||
| export default function RouteRedirect() { | ||
| const location = useLocation(); | ||
| const params = useParams(); | ||
| const navigate = useNavigate(); | ||
| const { chainId, accounts } = useContext(EthereumContext); | ||
|
|
||
| useEffect(() => { | ||
| const pathSegments = location.pathname.split("/"); | ||
| pathSegments[1] = chainId; | ||
|
|
||
| let newPath = pathSegments.join("/"); | ||
|
|
||
| if (location.pathname.includes("account")) { | ||
| if (!accounts[0]) { | ||
| newPath = chainId; | ||
| } else { | ||
| pathSegments[3] = accounts[0]; | ||
| newPath = pathSegments.join("/"); | ||
| } | ||
| } | ||
|
|
||
| if (params.contract && !Object.keys(networkMap[chainId].deployments).includes(params.contract)) { | ||
| newPath = chainId; | ||
| } | ||
|
|
||
| if (newPath !== location.pathname) { | ||
| navigate(newPath, { replace: true }); | ||
| } | ||
| }, [chainId, accounts[0], location.pathname, params.contract, navigate]); | ||
|
|
||
| return <Outlet />; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,30 +1,19 @@ | ||
| import React, { useContext } from "react"; | ||
| import { useNavigate } from "react-router-dom"; | ||
|
|
||
| import Select from "/src/components/presentational/select"; | ||
| import { EthereumContext, networkMap } from "../../../data/ethereumProvider"; | ||
|
|
||
| export default function ButtonSelectNetwork() { | ||
| const navigate = useNavigate(); | ||
| const ethereumContext = useContext(EthereumContext); | ||
| const { chainId, switchAppChain } = useContext(EthereumContext); | ||
|
|
||
| const selectOptions = Object.entries(networkMap).map(([chainId, props], index) => ({ | ||
| const selectOptions = Object.entries(networkMap).map(([chainId, props]) => ({ | ||
| value: chainId, | ||
| label: props.shortname, | ||
| })); | ||
|
|
||
| function handleOnChange(chainId) { | ||
| console.log({ chainId }); | ||
| navigate("/" + chainId + "/"); | ||
| // if (ethereumContext?.isProviderDetected) | ||
| // ethereum.request({ | ||
| // method: "wallet_switchEthereumChain", | ||
| // params: [{ chainId }], | ||
| // }); | ||
| } | ||
| return ( | ||
| <div style={{ marginLeft: "10px" }}> | ||
| <Select options={selectOptions} placeholder={networkMap[ethereumContext?.chainId]?.shortname} onChange={handleOnChange} /> | ||
| <Select options={selectOptions} placeholder={networkMap[chainId].shortname} onChange={switchAppChain} /> | ||
| </div> | ||
| ); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,138 +1,56 @@ | ||
| import React, { useState, useEffect, useContext } from "react"; | ||
| import React, { useState, useContext } from "react"; | ||
| import * as styles from "./index.module.scss"; | ||
|
|
||
| import ListArticlesItem from "/src/components/presentational/listArticlesItem"; | ||
| import Pagination from "/src/components/presentational/pagination"; | ||
| import Pill from "/src/components/presentational/pill"; | ||
|
|
||
| import { EthereumContext } from "/src/data/ethereumProvider"; | ||
| import getTrustScore from "/src/businessLogic/getTrustScore"; | ||
| import getTimePastSinceLastBountyUpdate from "/src/businessLogic/getTimePastSinceLastBountyUpdate"; | ||
| import { ipfsGateway } from "/src/utils/addToIPFS"; | ||
| import Pagination from "../../presentational/pagination"; | ||
|
|
||
| const PAGE_SIZE = 8; | ||
| const ITEMS_PER_PAGE = 8; | ||
|
|
||
| export default function ListArticles({ articles, isFetching }) { | ||
| const ethereumContext = useContext(EthereumContext); | ||
| const [articleContents, setArticleContents] = useState(); | ||
| const [loadingFetchingContents, setFetchingArticlesContents] = useState(true); | ||
| export default function ListArticles({ articles }) { | ||
| const [currentPage, setCurrentPage] = useState(1); | ||
|
|
||
| useEffect(() => { | ||
| let didCancel = false; | ||
|
|
||
| if (!articles) { | ||
| setFetchingArticlesContents(false); | ||
| return; | ||
| } | ||
| const fetchArticleData = async () => { | ||
| try { | ||
| const fetchPromises = articles | ||
| .filter((a) => a != null) | ||
| .map(async (article) => { | ||
| try { | ||
| const response = await fetch(ipfsGateway + article?.articleID); | ||
| if (!response.ok) { | ||
| throw new Error("Network response was not OK"); | ||
| } | ||
| const data = await response.json(); | ||
| return { | ||
| articleID: article.articleID, | ||
| title: data.title, | ||
| description: data.description, | ||
| tags: data.tags, | ||
| format: data.format | ||
| }; | ||
| } catch (error) { | ||
| console.error(error); | ||
| return null; | ||
| } | ||
| }); | ||
|
|
||
| const articleData = await Promise.all(fetchPromises); | ||
| const fetchedArticleContents = articleData.reduce( | ||
| (prevState, data) => ({ | ||
| ...prevState, | ||
| [data.articleID]: { title: data.title, description: data.description, tags: data.tags, format: data.format }, | ||
| }), | ||
| {} | ||
| ); | ||
|
|
||
| if (!didCancel) { | ||
| setArticleContents(fetchedArticleContents); | ||
| } | ||
| } catch (error) { | ||
| console.error(error); | ||
| } finally { | ||
| if (!didCancel) { | ||
| setFetchingArticlesContents(false); | ||
| } | ||
| } | ||
| }; | ||
|
|
||
| fetchArticleData(); | ||
| return () => { | ||
| didCancel = true; | ||
| }; | ||
| }, [articles]); | ||
| const { blockNumber, chainId, graphMetadata } = useContext(EthereumContext); | ||
| const currentBlockNumber = graphMetadata?.block?.number || blockNumber; | ||
|
|
||
| if (articles.length === 0) return <div>No news articles</div>; | ||
| return ( | ||
| <> | ||
| <div className={styles.containerItems}> | ||
| {articles && | ||
| Object.entries(articles.filter((c) => c != null)) | ||
| .sort(([, item1], [, item2]) => sortAccordingToTrustScore(item1, item2, ethereumContext)) | ||
| .slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE) | ||
| .map(([_key, value], index) => ( | ||
| <ListArticlesItem | ||
| key={value?.id} | ||
| title={ | ||
| articleContents?.[value?.articleID]?.title || | ||
| (!loadingFetchingContents && `Unable to fetch article data from ${value?.articleID}`) | ||
| } | ||
| description={articleContents?.[value?.articleID]?.description} | ||
| format={articleContents?.[value?.articleID]?.format} | ||
| linkTo={`/${ethereumContext?.chainId}/${value?.contractAddress}/${value?.id}/`} | ||
| score={getTrustScore( | ||
| value, | ||
| getTimePastSinceLastBountyUpdate( | ||
| value?.lastBalanceUpdate, | ||
| ethereumContext?.graphMetadata?.block?.number || ethereumContext?.blockNumber | ||
| ) | ||
| )} | ||
| createdAt={value?.createdAtTimestamp} | ||
| excerptSize={index % 2 == 1 ? 3 : 1} | ||
| > | ||
| <Pill modifiers="small">{value?.status}</Pill> | ||
| {articles | ||
| .sort((item1, item2) => sortAccordingToTrustScore(item1, item2, currentBlockNumber)) | ||
| .slice((currentPage - 1) * ITEMS_PER_PAGE, currentPage * ITEMS_PER_PAGE) | ||
| .map((article, index) => { | ||
| const { id, title, description, contractAddress, status, lastBalanceUpdate } = article; | ||
| const linkTo = `/${chainId}/${contractAddress}/${id}`; | ||
| const score = getTrustScore( | ||
| article, | ||
| getTimePastSinceLastBountyUpdate(lastBalanceUpdate, currentBlockNumber) | ||
| ); | ||
| const createdAt = article.createdAtTimestamp; | ||
| const excerptSize = index % 2 === 1 ? 3 : 1; | ||
| return ( | ||
| <ListArticlesItem {...{ key: id, title, description, linkTo, score, createdAt, excerptSize }}> | ||
| <Pill modifiers="small">{status}</Pill> | ||
| </ListArticlesItem> | ||
| ))} | ||
| ); | ||
| })} | ||
| </div> | ||
| {!isFetching && | ||
| (articles == null || (articles && articles.filter((a) => a != null).length == 0)) && | ||
| "No news articles."} | ||
| {articles && loadingFetchingContents && "Fetching article details."} | ||
|
|
||
| <Pagination | ||
| current={currentPage} | ||
| pageSize={PAGE_SIZE} | ||
| total={articles?.length} | ||
| pageSize={ITEMS_PER_PAGE} | ||
| total={articles.length} | ||
| onChange={(pageIndex) => setCurrentPage(pageIndex)} | ||
| /> | ||
| </> | ||
| ); | ||
| } | ||
|
|
||
| const sortAccordingToTrustScore = (item1, item2, ethereumContext) => | ||
| getTrustScore( | ||
| item2, | ||
| getTimePastSinceLastBountyUpdate( | ||
| item2?.lastBalanceUpdate, | ||
| ethereumContext?.graphMetadata?.block?.number || ethereumContext?.blockNumber | ||
| ) | ||
| ) - | ||
| getTrustScore( | ||
| item1, | ||
| getTimePastSinceLastBountyUpdate( | ||
| item1?.lastBalanceUpdate, | ||
| ethereumContext?.graphMetadata?.block?.number || ethereumContext?.blockNumber | ||
| ) | ||
| ); | ||
| const sortAccordingToTrustScore = (item1, item2, currentBlockNumber) => | ||
| getTrustScore(item2, getTimePastSinceLastBountyUpdate(item2.lastBalanceUpdate, currentBlockNumber)) - | ||
| getTrustScore(item1, getTimePastSinceLastBountyUpdate(item1.lastBalanceUpdate, currentBlockNumber)); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to erase the history?