From 8e59f928533bef3bb492647a813f23a5b17a4ada Mon Sep 17 00:00:00 2001 From: Tom Robiquet Date: Wed, 7 Feb 2024 10:54:19 +0200 Subject: [PATCH 01/10] refactor interface --- components/markets/market-card/index.tsx | 348 ++++++++++++----------- 1 file changed, 181 insertions(+), 167 deletions(-) diff --git a/components/markets/market-card/index.tsx b/components/markets/market-card/index.tsx index 65d8f6fca..95ef022fb 100644 --- a/components/markets/market-card/index.tsx +++ b/components/markets/market-card/index.tsx @@ -2,7 +2,7 @@ import type { ScalarRangeType } from "@zeitgeistpm/sdk"; import Skeleton from "components/ui/Skeleton"; import Decimal from "decimal.js"; import { ZTG } from "lib/constants"; -import { MarketOutcomes } from "lib/types/markets"; +import { MarketOutcome, MarketOutcomes } from "lib/types/markets"; import { formatNumberCompact } from "lib/util/format-compact"; import { hasDatePassed } from "lib/util/hasDatePassed"; import Link from "next/link"; @@ -49,19 +49,179 @@ export interface MarketType { scalar?: string[]; } -export interface MarketCardProps extends IndexedMarketCardData { +export interface MarketCardProps { + market: FullMarketFragment; + liquidity: string; + numParticipants: number; className?: string; disableLink?: boolean; } +export const MarketCard = ({ + market, + liquidity, + numParticipants, + className = "", + disableLink, +}: MarketCardProps) => { + const { + categories, + assets, + outcomeAssets, + marketType, + baseAsset, + marketId, + question, + pool, + neoPool, + scalarType, + status, + img, + } = market; + + const marketCategories: MarketOutcomes = + categories?.map((category, index) => { + const asset = assets[index]; + + const marketCategory: MarketOutcome = { + name: category.name ?? "", + assetId: outcomeAssets[index], + price: asset.price, + }; + + return marketCategory; + }) ?? []; + + const isYesNoMarket = + marketCategories.length === 2 && + marketCategories.some((outcome) => outcome.name.toLowerCase() === "yes") && + marketCategories.some((outcome) => outcome.name.toLowerCase() === "no"); + console.log("outcomes", marketCategories); + console.log(marketType.scalar); + console.log("yesno", isYesNoMarket); + + const prediction = marketCategories.reduce((prev, curr) => { + return prev && prev.price > curr.price ? prev : curr; + }); + + //always show "Yes" prediction percentage + const displayPrediction = + isYesNoMarket === true && prediction.name.toLowerCase() === "no" + ? { price: 1 - prediction.price, name: "Yes" } + : prediction; + + const lower = marketType?.scalar?.[0] + ? new Decimal(marketType?.scalar?.[0]).div(ZTG).toNumber() + : 0; + const upper = marketType?.scalar?.[1] + ? new Decimal(marketType?.scalar?.[1]).div(ZTG).toNumber() + : 0; + + const { data: image } = useMarketImage(market, { + fallback: + img && isAbsoluteUrl(img) && !isMarketImageBase64Encoded(img) + ? img + : undefined, + }); + + const { data: cmsMetadata } = useMarketCmsMetadata(marketId); + + return ( + +
+ { + if (disableLink) { + e.preventDefault(); + return; + } + }} + className={`flex flex-1 flex-col gap-4 ${ + disableLink && "cursor-default" + }`} + > +
+
+ {"Market +
+
+ {cmsMetadata?.question ?? question} +
+
+ +
+ {status === "Resolved" ? ( + + Resolved:{" "} + + {marketType?.categorical + ? displayPrediction.name + : formatNumberCompact(Number(displayPrediction.name))} + + + ) : (pool || neoPool) && marketType?.categorical ? ( + + ) : (pool || neoPool) && scalarType ? ( + + ) : ( + <> +
+ + No liquidity in this market + + + {lower} - {upper} + +
+
+ + )} +
+ + +
+
+ ); +}; + const MarketCardPredictionBar = ({ prediction: { name, price }, }: { prediction: { name: string; price: number }; }) => { + console.log(price); + // check if market has liquidity if (price != null) { const impliedPercentage = Math.round(Number(price) * 100); + console.log(impliedPercentage); return (
@@ -91,30 +251,26 @@ const MarketCardPredictionBar = ({ }; const MarketCardDetails = ({ - rows, + market, + liquidity, + numParticipants, }: { - rows: { - volume: number; - baseAsset: string; - outcomes: number; - endDate: string; - hasEnded: boolean; - numParticipants?: number; - liquidity?: string; - marketType: { categorical?: string; scalar?: string[] }; - }; + market: FullMarketFragment; + liquidity?: string; + numParticipants?: number; }) => { + const { period, baseAsset, outcomeAssets, volume } = market; const isEnding = () => { const currentTime = new Date(); - const endTime = Number(rows.endDate); + const endTime = Number(period.end); //6 hours in milliseconds const sixHours = 21600000; const diff = endTime - currentTime.getTime(); //checks if event has passed and is within 6 hours return diff < sixHours && diff > 0 ? true : false; }; - - const assetId = parseAssetId(rows.baseAsset).unwrap(); + const hasEnded = hasDatePassed(period.end); + const assetId = parseAssetId(baseAsset).unwrap(); const imagePath = IOForeignAssetId.is(assetId) ? lookupAssetImagePath(assetId.ForeignAsset) : IOBaseAssetId.is(assetId) @@ -125,9 +281,9 @@ const MarketCardDetails = ({
- {rows.endDate && - `${rows.hasEnded ? "Ended" : "Ends"} ${new Date( - Number(rows?.endDate), + {period.end && + `${hasEnded ? "Ended" : "Ends"} ${new Date( + Number(period.end), ).toLocaleString("en-US", { month: "short", day: "numeric", @@ -135,28 +291,28 @@ const MarketCardDetails = ({ {isEnding() && Ends Soon} - {rows.outcomes} outcomes{" "} + {outcomeAssets.length} outcomes{" "}
- {rows.numParticipants != undefined && rows.baseAsset ? ( + {numParticipants != undefined && baseAsset ? (
- {formatNumberCompact(rows.numParticipants, 2)} + {formatNumberCompact(numParticipants, 2)}
) : ( )}
- {formatNumberCompact(rows.volume, 2)} + {formatNumberCompact(volume, 2)}
- {rows.liquidity != undefined && rows.baseAsset ? ( + {liquidity != undefined && baseAsset ? (
{formatNumberCompact( - new Decimal(rows.liquidity).div(ZTG).toNumber(), + new Decimal(liquidity).div(ZTG).toNumber(), 2, )} @@ -176,146 +332,4 @@ const MarketCardDetails = ({ ); }; -export const MarketCard = ({ - marketId, - img, - question, - outcomes, - marketType, - prediction, - pool, - neoPool, - scalarType, - volume, - baseAsset, - endDate, - status, - className = "", - liquidity, - numParticipants, - tags, - disableLink, -}: MarketCardProps) => { - const isYesNoMarket = - outcomes.length === 2 && - outcomes.some((outcome) => outcome.name.toLowerCase() === "yes") && - outcomes.some((outcome) => outcome.name.toLowerCase() === "no"); - - //always show "Yes" prediction percentage - prediction = - isYesNoMarket === true && prediction.name.toLowerCase() === "no" - ? { price: 1 - prediction.price, name: "Yes" } - : prediction; - - const infoRows = { - marketType: marketType, - endDate: endDate, - hasEnded: hasDatePassed(Number(endDate)), - outcomes: outcomes.length, - volume: volume, - baseAsset: baseAsset, - liquidity, - numParticipants: numParticipants, - }; - - const lower = marketType?.scalar?.[0] - ? new Decimal(marketType?.scalar?.[0]).div(ZTG).toNumber() - : 0; - const upper = marketType?.scalar?.[1] - ? new Decimal(marketType?.scalar?.[1]).div(ZTG).toNumber() - : 0; - - const { data: image } = useMarketImage( - { marketId, tags }, - { - fallback: - img && isAbsoluteUrl(img) && !isMarketImageBase64Encoded(img) - ? img - : undefined, - }, - ); - - const { data: cmsMetadata } = useMarketCmsMetadata(marketId); - - return ( - -
- { - if (disableLink) { - e.preventDefault(); - return; - } - }} - className={`flex flex-1 flex-col gap-4 ${ - disableLink && "cursor-default" - }`} - > -
-
- {"Market -
-
- {cmsMetadata?.question ?? question} -
-
- -
- {status === "Resolved" ? ( - - Resolved:{" "} - - {marketType?.categorical - ? prediction.name - : formatNumberCompact(Number(prediction.name))} - - - ) : (pool || neoPool) && marketType?.categorical ? ( - - ) : (pool || neoPool) && scalarType ? ( - - ) : ( - <> -
- - No liquidity in this market - - - {lower} - {upper} - -
-
- - )} -
- - -
-
- ); -}; - export default MarketCard; From 699cdae357d0b4106cc31bbaa10e4ca78f6e855c Mon Sep 17 00:00:00 2001 From: Tom Robiquet Date: Wed, 7 Feb 2024 12:07:05 +0200 Subject: [PATCH 02/10] Show base asset logo on portfolio positions --- components/portfolio/MarketPositionHeader.tsx | 23 ++++++++++++++++++- components/portfolio/MarketPositions.tsx | 1 + 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/components/portfolio/MarketPositionHeader.tsx b/components/portfolio/MarketPositionHeader.tsx index 2bd96afd5..a3ecaa540 100644 --- a/components/portfolio/MarketPositionHeader.tsx +++ b/components/portfolio/MarketPositionHeader.tsx @@ -1,14 +1,35 @@ +import { IOBaseAssetId, IOForeignAssetId } from "@zeitgeistpm/sdk"; +import { lookupAssetImagePath } from "lib/constants/foreign-asset"; +import { parseAssetIdString } from "lib/util/parse-asset-id"; +import Image from "next/image"; import Link from "next/link"; const MarketPositionHeader = ({ marketId, question, + baseAsset, }: { marketId: number; question?: string; + baseAsset: string; }) => { + const baseAssetId = parseAssetIdString(baseAsset); + lookupAssetImagePath(); + const imagePath = IOForeignAssetId.is(baseAssetId) + ? lookupAssetImagePath(baseAssetId.ForeignAsset) + : IOBaseAssetId.is(baseAssetId) + ? lookupAssetImagePath(baseAssetId.Ztg) + : ""; + return ( -

+

+ Currency token logo {question}

); diff --git a/components/portfolio/MarketPositions.tsx b/components/portfolio/MarketPositions.tsx index df543f970..b7ef68e80 100644 --- a/components/portfolio/MarketPositions.tsx +++ b/components/portfolio/MarketPositions.tsx @@ -176,6 +176,7 @@ export const MarketPositions = ({ Date: Thu, 8 Feb 2024 17:32:44 +0200 Subject: [PATCH 03/10] market list refactor --- components/markets/MarketsList.tsx | 34 +---------------- components/markets/market-card/index.tsx | 48 ++++++++---------------- lib/hooks/queries/useInfiniteMarkets.ts | 29 +++----------- 3 files changed, 23 insertions(+), 88 deletions(-) diff --git a/components/markets/MarketsList.tsx b/components/markets/MarketsList.tsx index 425207cad..d7a87f84d 100644 --- a/components/markets/MarketsList.tsx +++ b/components/markets/MarketsList.tsx @@ -118,44 +118,14 @@ const MarketsList = ({
{markets?.map((market) => { - const volume = market.volume; - const scalarType = market.scalarType as ScalarRangeType; const stat = stats?.find((s) => s.marketId === market.marketId); - const question = market.question ?? ""; - const image = market.img ?? ""; - //check if market is categorical or scalar - let { categorical, scalar } = market.marketType ?? {}; - if (categorical === null) { - categorical = ""; - } - const filteredScalar = - scalar?.filter((item): item is string => item !== null) ?? []; - const marketType = { categorical, scalar: filteredScalar }; - const pool = market.pool ?? null; - const tags = - market.tags?.filter((tag): tag is string => tag !== null) ?? []; return ( ); })} diff --git a/components/markets/market-card/index.tsx b/components/markets/market-card/index.tsx index 6f2b27180..f6622ae10 100644 --- a/components/markets/market-card/index.tsx +++ b/components/markets/market-card/index.tsx @@ -27,27 +27,6 @@ const MarketFavoriteToggle = dynamic(() => import("../MarketFavoriteToggle"), { ssr: false, }); -export interface IndexedMarketCardData { - marketId: number; - img?: string; - question: string; - creation: string; - creator: string; - outcomes: MarketOutcomes; - marketType: MarketType; - scalarType: ScalarRangeType | null; - prediction: { name: string; price: number }; - volume: number; - pool?: { poolId?: number } | null; - neoPool?: FullMarketFragment["neoPool"] | null; - baseAsset: string; - tags?: string[]; - status: string; - endDate: string; - liquidity?: string; - numParticipants?: number; -} - export interface MarketType { categorical?: string; scalar?: string[]; @@ -55,8 +34,8 @@ export interface MarketType { export interface MarketCardProps { market: FullMarketFragment; - liquidity: string; - numParticipants: number; + liquidity?: string; + numParticipants?: number; className?: string; disableLink?: boolean; } @@ -104,13 +83,16 @@ export const MarketCard = ({ console.log(marketType.scalar); console.log("yesno", isYesNoMarket); - const prediction = marketCategories.reduce((prev, curr) => { - return prev && prev.price > curr.price ? prev : curr; - }); + const prediction = + marketCategories.length > 0 + ? marketCategories?.reduce((prev, curr) => { + return prev && prev.price > curr.price ? prev : curr; + }) + : undefined; //always show "Yes" prediction percentage const displayPrediction = - isYesNoMarket === true && prediction.name.toLowerCase() === "no" + isYesNoMarket === true && prediction?.name.toLowerCase() === "no" ? { price: 1 - prediction.price, name: "Yes" } : prediction; @@ -175,19 +157,21 @@ export const MarketCard = ({ Resolved:{" "} {marketType?.categorical - ? displayPrediction.name - : formatNumberCompact(Number(displayPrediction.name))} + ? displayPrediction?.name + : formatNumberCompact(Number(displayPrediction?.name))} ) : (pool || neoPool) && marketType?.categorical ? ( - + displayPrediction && ( + + ) ) : (pool || neoPool) && scalarType ? ( ) : ( diff --git a/lib/hooks/queries/useInfiniteMarkets.ts b/lib/hooks/queries/useInfiniteMarkets.ts index 6db439de5..7532609c8 100644 --- a/lib/hooks/queries/useInfiniteMarkets.ts +++ b/lib/hooks/queries/useInfiniteMarkets.ts @@ -12,13 +12,13 @@ import { MarketsOrderBy, } from "lib/types/market-filter"; import { MarketOutcomes } from "lib/types/markets"; -import { getCurrentPrediction } from "lib/util/assets"; import { useSdkv2 } from "../useSdkv2"; +import { FullMarketFragment } from "@zeitgeistpm/indexer"; +import { CmsMarketMetadata } from "lib/cms/markets"; +import { marketCmsDatakeyForMarket } from "./cms/useMarketCmsMetadata"; import { marketMetaFilter } from "./constants"; import { marketsRootQuery } from "./useMarket"; -import { marketCmsDatakeyForMarket } from "./cms/useMarketCmsMetadata"; -import { CmsMarketMetadata } from "lib/cms/markets"; export const rootKey = "markets-filtered"; @@ -50,7 +50,7 @@ export const useInfiniteMarkets = ( const limit = 12; const fetcher = async ({ pageParam = 0, - }): Promise<{ data: QueryMarketData[]; next: number | boolean }> => { + }): Promise<{ data: FullMarketFragment[]; next: number | boolean }> => { if ( !isIndexedSdk(sdk) || filters == null || @@ -115,27 +115,8 @@ export const useInfiniteMarkets = ( if (cmsData?.imageUrl) market.img = cmsData.imageUrl; } - const resMarkets: Array = markets.map((market) => { - const outcomes: MarketOutcomes = market.assets.map((asset, index) => { - return { - price: asset.price, - name: market.categories?.[index].name ?? "", - assetId: asset.assetId, - amountInPool: asset.amountInPool, - }; - }); - - const prediction = getCurrentPrediction(outcomes, market); - - return { - ...market, - outcomes, - prediction, - }; - }); - return { - data: resMarkets, + data: markets, next: markets.length >= limit ? pageParam + 1 : false, }; }; From 0b037addf9f05b22c6a84b809dc393cb43bf536f Mon Sep 17 00:00:00 2001 From: Tom Robiquet Date: Thu, 8 Feb 2024 17:53:40 +0200 Subject: [PATCH 04/10] refactor remaining cards --- components/markets/FavoriteMarketsList.tsx | 41 ++------------ components/markets/MarketScroll.tsx | 17 +++--- components/markets/SimilarMarketsSection.tsx | 30 +---------- components/portfolio/BondsTable.tsx | 1 + lib/cms/topics.ts | 56 +++----------------- lib/gql/featured-markets.ts | 54 ++----------------- lib/gql/trending-markets.ts | 42 ++------------- lib/hooks/queries/useFavoriteMarkets.ts | 29 ++-------- lib/hooks/queries/useRecommendedMarkets.ts | 33 +----------- pages/index.tsx | 33 ++++++------ pages/topics/[topic].tsx | 8 +-- 11 files changed, 54 insertions(+), 290 deletions(-) diff --git a/components/markets/FavoriteMarketsList.tsx b/components/markets/FavoriteMarketsList.tsx index 5d75694c0..4cf90e456 100644 --- a/components/markets/FavoriteMarketsList.tsx +++ b/components/markets/FavoriteMarketsList.tsx @@ -1,11 +1,7 @@ -import { ScalarRangeType } from "@zeitgeistpm/sdk"; -import Decimal from "decimal.js"; -import { ZTG } from "lib/constants"; import { useFavoriteMarkets } from "lib/hooks/queries/useFavoriteMarkets"; import { useMarketsStats } from "lib/hooks/queries/useMarketsStats"; -import Loader from "react-spinners/PulseLoader"; +import { MdFavorite } from "react-icons/md"; import MarketCard from "./market-card/index"; -import { MdFavorite, MdFavoriteBorder } from "react-icons/md"; export type FavoriteMarketsListProps = { className?: string; @@ -36,44 +32,13 @@ const FavoriteMarketsList = ({ className = "" }: FavoriteMarketsListProps) => {
{markets?.map((market) => { - const volume = market.volume; - const scalarType = market.scalarType as ScalarRangeType; const stat = stats?.find((s) => s.marketId === market.marketId); - const question = market.question ?? ""; - const image = market.img ?? ""; - //check if market is categorical or scalar - let { categorical, scalar } = market.marketType ?? {}; - if (categorical === null) { - categorical = ""; - } - const filteredScalar = - scalar?.filter((item): item is string => item !== null) ?? []; - const marketType = { categorical, scalar: filteredScalar }; - const pool = market.pool ?? null; - const tags = - market.tags?.filter((tag): tag is string => tag !== null) ?? []; - return ( ); })} diff --git a/components/markets/MarketScroll.tsx b/components/markets/MarketScroll.tsx index 24e724180..36346fa4f 100644 --- a/components/markets/MarketScroll.tsx +++ b/components/markets/MarketScroll.tsx @@ -3,11 +3,12 @@ import { BREAKPOINTS } from "lib/constants/breakpoints"; import { useWindowSize } from "lib/hooks/events/useWindowSize"; import { useMarketsStats } from "lib/hooks/queries/useMarketsStats"; import { range } from "lodash-es"; -import { useEffect, useLayoutEffect, useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { useResizeDetector } from "react-resize-detector"; -import MarketCard, { IndexedMarketCardData } from "./market-card/index"; +import MarketCard from "./market-card/index"; import { useDebouncedCallback } from "use-debounce"; import { useHasMounted } from "lib/hooks/events/useHasMounted"; +import { FullMarketFragment } from "@zeitgeistpm/indexer"; const MarketScroll = ({ title, @@ -17,7 +18,7 @@ const MarketScroll = ({ }: { title: string; cta?: string; - markets: IndexedMarketCardData[]; + markets: FullMarketFragment[]; link?: string; }) => { const scrollRef = useRef(null); @@ -114,12 +115,6 @@ const MarketScroll = ({ const isShown = showRange.includes(cardIndex) || windowWidth < BREAKPOINTS.md; - market = { - ...market, - numParticipants: stat?.participants, - liquidity: stat?.liquidity, - }; - return ( ); })} diff --git a/components/markets/SimilarMarketsSection.tsx b/components/markets/SimilarMarketsSection.tsx index f3e2325d9..7b35bb43d 100644 --- a/components/markets/SimilarMarketsSection.tsx +++ b/components/markets/SimilarMarketsSection.tsx @@ -42,15 +42,6 @@ export const SimilarMarketsSection = ({ {recommendedMarkets?.markets.map((market, index) => { const stat = stats?.find((s) => s.marketId === market.marketId); - let { categorical, scalar } = market.marketType ?? {}; - if (categorical === null) { - categorical = ""; - } - const filteredScalar = - scalar?.filter((item): item is string => item !== null) ?? []; - const marketType = { categorical, scalar: filteredScalar }; - const scalarType = market.scalarType as ScalarRangeType; - return (
tag !== null) ?? - [] - } + key={market.marketId} + market={market} numParticipants={stat?.participants} liquidity={stat?.liquidity} /> diff --git a/components/portfolio/BondsTable.tsx b/components/portfolio/BondsTable.tsx index 192094acc..ece2135e3 100644 --- a/components/portfolio/BondsTable.tsx +++ b/components/portfolio/BondsTable.tsx @@ -50,6 +50,7 @@ const BondsTable = ({ address }: { address: string }) => {
{ if (!market || !market.categories) return; - const marketCategories: MarketOutcomes = market.categories - .map((category, index) => { - const asset = market.assets[index]; - - if (!asset) return; - - const marketCategory: MarketOutcome = { - name: category.name ?? "", - assetId: market.outcomeAssets[index], - price: asset.price, - }; - - return marketCategory; - }) - .filter(isNotNull); - - const prediction = getCurrentPrediction(market.assets, market); - - const marketCardData: IndexedMarketCardData = { - marketId: market.marketId, - question: market.question ?? "", - creation: market.creation, - img: market.img ?? "", - prediction: prediction, - creator: market.creator, - volume: Number(new Decimal(market?.volume ?? 0).div(ZTG).toFixed(0)), - baseAsset: market.baseAsset, - outcomes: marketCategories, - pool: market.pool ?? null, - neoPool: market.neoPool, - marketType: market.marketType as any, - tags: market.tags?.filter(isNotNull), - status: market.status, - scalarType: (market.scalarType ?? null) as "number" | "date" | null, - endDate: market.period.end, - numParticipants: stats.find((s) => s.marketId === market.marketId) - ?.participants, - liquidity: stats.find((s) => s.marketId === market.marketId)?.liquidity, + return { + market, + stats: stats.find((s) => s.marketId === market.marketId), }; - - return marketCardData; }) .filter(isNotNull); marketCardsData.sort((a, b) => { return ( - topic.marketIds?.findIndex((m) => m === a.marketId) - - topic.marketIds?.findIndex((m) => m === b.marketId) + topic.marketIds?.findIndex((m) => m === a.market.marketId) - + topic.marketIds?.findIndex((m) => m === b.market.marketId) ); }); diff --git a/lib/gql/featured-markets.ts b/lib/gql/featured-markets.ts index 507e2a68f..233e9edc4 100644 --- a/lib/gql/featured-markets.ts +++ b/lib/gql/featured-markets.ts @@ -1,20 +1,12 @@ -import Decimal from "decimal.js"; +import { FullMarketFragment } from "@zeitgeistpm/indexer"; +import { FullContext, Sdk } from "@zeitgeistpm/sdk"; import { GraphQLClient } from "graphql-request"; -import { FullContext, ScalarRangeType, Sdk } from "@zeitgeistpm/sdk"; -import { - IndexedMarketCardData, - MarketType, -} from "components/markets/market-card/index"; -import { ZTG } from "lib/constants"; -import { MarketOutcome, MarketOutcomes } from "lib/types/markets"; import { getCmsFeaturedMarkets } from "lib/cms/featured-markets"; -import { isPresent } from "lib/types"; -import { getCurrentPrediction } from "lib/util/assets"; const getFeaturedMarkets = async ( client: GraphQLClient, sdk: Sdk, -): Promise => { +): Promise => { const cmsFeaturedMarkets = await getCmsFeaturedMarkets(); const { markets } = await sdk.indexer.markets({ @@ -23,50 +15,14 @@ const getFeaturedMarkets = async ( }, }); - let featuredMarkets: IndexedMarketCardData[] = markets.map((market) => { - const marketCategories: MarketOutcomes = - market.categories?.map((category, index) => { - const asset = market.assets[index]; - const marketCategory: MarketOutcome = { - name: category.name ?? "", - assetId: market.outcomeAssets[index], - price: asset?.price ?? 0, - }; - - return marketCategory; - }) ?? []; - - const prediction = getCurrentPrediction(market.assets, market); - - const cardMarket: IndexedMarketCardData = { - marketId: market.marketId, - question: market.question ?? "", - creation: market.creation, - creator: market.creator, - img: market.img ?? "", - prediction: prediction, - volume: new Decimal(market.volume ?? 0).div(ZTG).toNumber(), - baseAsset: market.baseAsset, - outcomes: marketCategories, - pool: market.pool, - neoPool: market.neoPool, - marketType: market.marketType as MarketType, - scalarType: (market.scalarType ?? null) as ScalarRangeType, - tags: market.tags?.filter(isPresent) ?? [], - status: market.status, - endDate: market.period.end, - }; - return cardMarket; - }); - - featuredMarkets.sort((a, b) => { + markets.sort((a, b) => { return ( cmsFeaturedMarkets.marketIds?.findIndex((m) => m === a.marketId) - cmsFeaturedMarkets.marketIds?.findIndex((m) => m === b.marketId) ); }); - return featuredMarkets; + return markets; }; export default getFeaturedMarkets; diff --git a/lib/gql/trending-markets.ts b/lib/gql/trending-markets.ts index 866704288..f6e5c5bc3 100644 --- a/lib/gql/trending-markets.ts +++ b/lib/gql/trending-markets.ts @@ -10,7 +10,6 @@ import { Sdk, } from "@zeitgeistpm/sdk"; import { isNotNull } from "@zeitgeistpm/utility/dist/null"; -import { IndexedMarketCardData } from "components/markets/market-card/index"; import Decimal from "decimal.js"; import { GraphQLClient, gql } from "graphql-request"; import { DAY_SECONDS, ZTG } from "lib/constants"; @@ -24,6 +23,7 @@ import { MarketOutcome, MarketOutcomes } from "lib/types/markets"; import { getCurrentPrediction } from "lib/util/assets"; import { fetchAllPages } from "lib/util/fetch-all-pages"; import { parseAssetIdString } from "lib/util/parse-asset-id"; +import { FullMarketFragment } from "@zeitgeistpm/indexer"; const marketChangesQuery = gql` query MarketChanges($start: DateTime, $end: DateTime) { @@ -42,7 +42,7 @@ const marketChangesQuery = gql` const getTrendingMarkets = async ( client: GraphQLClient, sdk: Sdk, -): Promise => { +): Promise => { const now = new Date().toISOString(); const dateOneWeekAgo = new Date( new Date().getTime() - DAY_SECONDS * 7 * 1000, @@ -87,43 +87,7 @@ const getTrendingMarkets = async ( (market) => market.marketId === Number(marketId), ); - if (!market || !market.categories) return; - const marketCategories: MarketOutcomes = market.categories.map( - (category, index) => { - const asset = market.assets[index]; - - const marketCategory: MarketOutcome = { - name: category.name ?? "", - assetId: market.outcomeAssets[index], - price: asset.price, - }; - - return marketCategory; - }, - ); - - const prediction = getCurrentPrediction(market.assets, market); - - const trendingMarket: IndexedMarketCardData = { - marketId: market.marketId, - question: market.question ?? "", - creation: market.creation, - img: market.img ?? "", - prediction: prediction, - creator: market.creator, - volume: Number(new Decimal(market?.volume ?? 0).div(ZTG).toFixed(0)), - baseAsset: market.baseAsset, - outcomes: marketCategories, - pool: market.pool ?? null, - neoPool: market.neoPool, - marketType: market.marketType as any, - tags: market.tags?.filter(isNotNull), - status: market.status, - scalarType: (market.scalarType ?? null) as "number" | "date" | null, - endDate: market.period.end, - }; - - return trendingMarket; + return market; }); return tm.filter(isNotNull); diff --git a/lib/hooks/queries/useFavoriteMarkets.ts b/lib/hooks/queries/useFavoriteMarkets.ts index 0ef22f38d..63b0c58c0 100644 --- a/lib/hooks/queries/useFavoriteMarkets.ts +++ b/lib/hooks/queries/useFavoriteMarkets.ts @@ -1,11 +1,11 @@ import { useQuery, useQueryClient } from "@tanstack/react-query"; +import { FullMarketFragment } from "@zeitgeistpm/indexer"; import { IndexerContext, Market, isIndexedSdk } from "@zeitgeistpm/sdk"; +import { CmsMarketMetadata } from "lib/cms/markets"; +import { useFavoriteMarketsStorage } from "lib/state/favorites"; import { MarketOutcomes } from "lib/types/markets"; -import { getCurrentPrediction } from "lib/util/assets"; import { useSdkv2 } from "../useSdkv2"; -import { CmsMarketMetadata } from "lib/cms/markets"; import { marketCmsDatakeyForMarket } from "./cms/useMarketCmsMetadata"; -import { useFavoriteMarketsStorage } from "lib/state/favorites"; export const rootKey = "markets-favorites"; @@ -19,7 +19,7 @@ export const useFavoriteMarkets = () => { const queryClient = useQueryClient(); const storage = useFavoriteMarketsStorage(); - const fetcher = async (): Promise => { + const fetcher = async (): Promise => { if (!isIndexedSdk(sdk)) { return null; } @@ -38,26 +38,7 @@ export const useFavoriteMarkets = () => { if (cmsData?.imageUrl) market.img = cmsData.imageUrl; } - const resMarkets: Array = markets.map((market) => { - const outcomes: MarketOutcomes = market.assets.map((asset, index) => { - return { - price: asset.price, - name: market.categories?.[index].name ?? "", - assetId: asset.assetId, - amountInPool: asset.amountInPool, - }; - }); - - const prediction = getCurrentPrediction(outcomes, market); - - return { - ...market, - outcomes, - prediction, - }; - }); - - return resMarkets; + return markets; }; const query = useQuery({ diff --git a/lib/hooks/queries/useRecommendedMarkets.ts b/lib/hooks/queries/useRecommendedMarkets.ts index 0a2f07243..fbfcdbc51 100644 --- a/lib/hooks/queries/useRecommendedMarkets.ts +++ b/lib/hooks/queries/useRecommendedMarkets.ts @@ -32,12 +32,7 @@ export const useRecommendedMarkets = (marketId?: number, limit = 2) => { if (market.question && similarMarkets.length > 0) { return { - markets: await mapMarkets( - sdk.indexer, - similarMarkets - .filter((m) => m.question !== market.question) - .slice(0, 2), - ), + markets: similarMarkets, type: "similar" as const, }; } else { @@ -51,7 +46,7 @@ export const useRecommendedMarkets = (marketId?: number, limit = 2) => { }, }); return { - markets: await mapMarkets(sdk.indexer, popularMarkets), + markets: popularMarkets, type: "popular" as const, }; } @@ -65,27 +60,3 @@ export const useRecommendedMarkets = (marketId?: number, limit = 2) => { return query; }; - -const mapMarkets = async ( - indexer: ZeitgeistIndexer, - markets: FullMarketFragment[], -) => { - const outcomes = await getOutcomesForMarkets(indexer.client, markets); - - let resMarkets: Array = []; - - for (const market of markets) { - const marketOutcomes = outcomes[market.marketId]; - const prediction = - market && market.assets.length > 0 - ? getCurrentPrediction(market.assets, market) - : { name: "None", price: 0 }; - - resMarkets = [ - ...resMarkets, - { ...market, outcomes: marketOutcomes, prediction }, - ]; - } - - return resMarkets; -}; diff --git a/pages/index.tsx b/pages/index.tsx index 24f06003d..d92a0a5b1 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,25 +1,22 @@ -import { Disclosure } from "@headlessui/react"; import { GenericChainProperties } from "@polkadot/types"; import { dehydrate, QueryClient } from "@tanstack/react-query"; +import { FullMarketFragment } from "@zeitgeistpm/indexer"; import { create, ZeitgeistIpfs } from "@zeitgeistpm/sdk"; import { BgBallGfx } from "components/front-page/BgBallFx"; import GettingStartedSection from "components/front-page/GettingStartedSection"; import { HeroBanner } from "components/front-page/HeroBanner"; import LatestTrades from "components/front-page/LatestTrades"; -import NetworkStats from "components/front-page/NetworkStats"; import { NewsSection } from "components/front-page/News"; import PopularCategories, { CATEGORIES, } from "components/front-page/PopularCategories"; import { Topics } from "components/front-page/Topics"; import WatchHow from "components/front-page/WatchHow"; -import MarketCard, { - IndexedMarketCardData, -} from "components/markets/market-card"; import MarketScroll from "components/markets/MarketScroll"; +import MarketCard from "components/markets/market-card"; import { GraphQLClient } from "graphql-request"; import { getCmsMarketMetadataForAllMarkets } from "lib/cms/markets"; -import { getCmsNews, CmsNews } from "lib/cms/news"; +import { CmsNews, getCmsNews } from "lib/cms/news"; import { CmsTopicHeader, getCmsTopicHeaders, @@ -28,6 +25,7 @@ import { import { endpointOptions, environment, graphQlEndpoint } from "lib/constants"; import getFeaturedMarkets from "lib/gql/featured-markets"; import { getNetworkStats } from "lib/gql/get-network-stats"; +import { MarketStats } from "lib/gql/markets-stats"; import { getCategoryCounts } from "lib/gql/popular-categories"; import getTrendingMarkets from "lib/gql/trending-markets"; import { marketCmsDatakeyForMarket } from "lib/hooks/queries/cms/useMarketCmsMetadata"; @@ -38,16 +36,10 @@ import { import { categoryCountsKey } from "lib/hooks/queries/useCategoryCounts"; import { getPlaiceholders } from "lib/util/getPlaiceHolders"; import { NextPage } from "next"; -import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/router"; import path from "path"; -import { - getPlaiceholder, - IGetPlaiceholderOptions, - IGetPlaiceholderReturn, -} from "plaiceholder"; -import { useState } from "react"; +import { getPlaiceholder } from "plaiceholder"; export async function getStaticProps() { const client = new GraphQLClient(graphQlEndpoint); @@ -149,8 +141,8 @@ export async function getStaticProps() { const IndexPage: NextPage<{ news: CmsNews[]; - featuredMarkets: IndexedMarketCardData[]; - trendingMarkets: IndexedMarketCardData[]; + featuredMarkets: FullMarketFragment[]; + trendingMarkets: FullMarketFragment[]; categoryPlaceholders: string[]; newsImagePlaceholders: string[]; topicImagePlaceholders: string[]; @@ -161,7 +153,7 @@ const IndexPage: NextPage<{ cmsTopics: CmsTopicHeader[]; topicsMarkets: { topic: CmsTopicHeader; - markets: IndexedMarketCardData[]; + markets: { market: FullMarketFragment; stats: MarketStats }[]; }[]; }> = ({ news, @@ -215,8 +207,13 @@ const IndexPage: NextPage<{ {topic && topic.topic.marketIds && ( <>
- {topic.markets.map((market) => ( - + {topic.markets.map(({ market, stats }) => ( + ))}
diff --git a/pages/topics/[topic].tsx b/pages/topics/[topic].tsx index a6620fe6c..a67d26e77 100644 --- a/pages/topics/[topic].tsx +++ b/pages/topics/[topic].tsx @@ -1,8 +1,7 @@ import { PortableText } from "@portabletext/react"; +import { FullMarketFragment } from "@zeitgeistpm/indexer"; import { ZeitgeistIpfs, create } from "@zeitgeistpm/sdk"; -import MarketCard, { - IndexedMarketCardData, -} from "components/markets/market-card"; +import MarketCard from "components/markets/market-card"; import { sanityImageBuilder } from "lib/cms/sanity"; import { CmsTopicFull, @@ -11,6 +10,7 @@ import { marketsForTopic, } from "lib/cms/topics"; import { endpointOptions, graphQlEndpoint } from "lib/constants"; +import { MarketStats } from "lib/gql/markets-stats"; import { NextPage } from "next"; import Image from "next/image"; import Link from "next/link"; @@ -50,7 +50,7 @@ export async function getStaticProps({ const TopicPage: NextPage<{ cmsTopic: CmsTopicFull; - markets: IndexedMarketCardData[]; + markets: { market: FullMarketFragment; stats: MarketStats }[]; }> = ({ cmsTopic, markets }) => { if (process.env.NEXT_PUBLIC_SHOW_TOPICS !== "true") { return ; From b71a1a1207abaf88dc5ba3453287f23cc6c9bb83 Mon Sep 17 00:00:00 2001 From: Tom Robiquet Date: Thu, 8 Feb 2024 18:09:14 +0200 Subject: [PATCH 05/10] fixes --- components/markets/market-card/index.tsx | 8 +------- lib/hooks/queries/useRecommendedMarkets.ts | 14 ++++---------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/components/markets/market-card/index.tsx b/components/markets/market-card/index.tsx index f6622ae10..e2620fd69 100644 --- a/components/markets/market-card/index.tsx +++ b/components/markets/market-card/index.tsx @@ -69,7 +69,7 @@ export const MarketCard = ({ const marketCategory: MarketOutcome = { name: category.name ?? "", assetId: outcomeAssets[index], - price: asset.price, + price: asset?.price, }; return marketCategory; @@ -79,9 +79,6 @@ export const MarketCard = ({ marketCategories.length === 2 && marketCategories.some((outcome) => outcome.name.toLowerCase() === "yes") && marketCategories.some((outcome) => outcome.name.toLowerCase() === "no"); - console.log("outcomes", marketCategories); - console.log(marketType.scalar); - console.log("yesno", isYesNoMarket); const prediction = marketCategories.length > 0 @@ -209,12 +206,9 @@ const MarketCardPredictionBar = ({ }: { prediction: { name: string; price: number }; }) => { - console.log(price); - // check if market has liquidity if (price != null) { const impliedPercentage = Math.round(Number(price) * 100); - console.log(impliedPercentage); return (
diff --git a/lib/hooks/queries/useRecommendedMarkets.ts b/lib/hooks/queries/useRecommendedMarkets.ts index fbfcdbc51..2d002de59 100644 --- a/lib/hooks/queries/useRecommendedMarkets.ts +++ b/lib/hooks/queries/useRecommendedMarkets.ts @@ -1,15 +1,7 @@ import { useQuery } from "@tanstack/react-query"; -import { - FullMarketFragment, - MarketOrderByInput, - MarketStatus, - ZeitgeistIndexer, -} from "@zeitgeistpm/indexer"; +import { MarketOrderByInput, MarketStatus } from "@zeitgeistpm/indexer"; import { isIndexedSdk } from "@zeitgeistpm/sdk"; -import { getOutcomesForMarkets } from "lib/gql/markets-list/outcomes-for-markets"; -import { getCurrentPrediction } from "lib/util/assets"; import { useSdkv2 } from "../useSdkv2"; -import { QueryMarketData } from "./useInfiniteMarkets"; import { useMarket } from "./useMarket"; import { searchMarketsText } from "./useMarketSearch"; @@ -32,7 +24,9 @@ export const useRecommendedMarkets = (marketId?: number, limit = 2) => { if (market.question && similarMarkets.length > 0) { return { - markets: similarMarkets, + markets: similarMarkets + .filter((m) => m.question !== market.question) + .slice(0, 2), type: "similar" as const, }; } else { From 341b386f58309802ac692e6edcfd5590cac5d736 Mon Sep 17 00:00:00 2001 From: Tom Robiquet Date: Thu, 8 Feb 2024 18:10:29 +0200 Subject: [PATCH 06/10] add back line clamp --- components/markets/market-card/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/markets/market-card/index.tsx b/components/markets/market-card/index.tsx index e2620fd69..1c2848eaa 100644 --- a/components/markets/market-card/index.tsx +++ b/components/markets/market-card/index.tsx @@ -213,7 +213,7 @@ const MarketCardPredictionBar = ({ return (
- {name} + {name} {impliedPercentage}%
Date: Thu, 8 Feb 2024 18:15:25 +0200 Subject: [PATCH 07/10] fix volume formatting --- components/markets/market-card/index.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/markets/market-card/index.tsx b/components/markets/market-card/index.tsx index 1c2848eaa..341848176 100644 --- a/components/markets/market-card/index.tsx +++ b/components/markets/market-card/index.tsx @@ -62,6 +62,8 @@ export const MarketCard = ({ img, } = market; + console.log(liquidity); + const marketCategories: MarketOutcomes = categories?.map((category, index) => { const asset = assets[index]; @@ -292,7 +294,9 @@ const MarketCardDetails = ({ )}
- {formatNumberCompact(volume, 2)} + + {formatNumberCompact(new Decimal(volume).div(ZTG).toNumber(), 2)} +
{liquidity != undefined && baseAsset ? (
From c0ad3f56ef079cd667d18cfb5b3177565320f43f Mon Sep 17 00:00:00 2001 From: Tom Robiquet Date: Mon, 12 Feb 2024 11:43:20 +0200 Subject: [PATCH 08/10] fix resolution display --- components/markets/market-card/index.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/components/markets/market-card/index.tsx b/components/markets/market-card/index.tsx index 341848176..b77b2911f 100644 --- a/components/markets/market-card/index.tsx +++ b/components/markets/market-card/index.tsx @@ -60,10 +60,9 @@ export const MarketCard = ({ scalarType, status, img, + resolvedOutcome, } = market; - console.log(liquidity); - const marketCategories: MarketOutcomes = categories?.map((category, index) => { const asset = assets[index]; @@ -151,13 +150,13 @@ export const MarketCard = ({
- {status === "Resolved" ? ( + {status === "Resolved" && resolvedOutcome ? ( Resolved:{" "} {marketType?.categorical - ? displayPrediction?.name - : formatNumberCompact(Number(displayPrediction?.name))} + ? marketCategories[resolvedOutcome].name + : formatNumberCompact(Number(resolvedOutcome) / ZTG)} ) : (pool || neoPool) && marketType?.categorical ? ( From 59b64cfd6186d77707ceef7f495fac801b94edee Mon Sep 17 00:00:00 2001 From: Tom Robiquet Date: Tue, 13 Feb 2024 09:44:57 +0200 Subject: [PATCH 09/10] remove old query --- lib/gql/markets-list/outcomes-for-markets.ts | 107 ------------------- 1 file changed, 107 deletions(-) delete mode 100644 lib/gql/markets-list/outcomes-for-markets.ts diff --git a/lib/gql/markets-list/outcomes-for-markets.ts b/lib/gql/markets-list/outcomes-for-markets.ts deleted file mode 100644 index 5544c99ae..000000000 --- a/lib/gql/markets-list/outcomes-for-markets.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { gql, GraphQLClient } from "graphql-request"; -import { MarketOutcomes } from "lib/types/markets"; - -const assetsQuery = gql` - query AssetsForPools($poolIds: [Int!]) { - assets(where: { pool: { poolId_in: $poolIds } }) { - price - assetId - amountInPool - pool { - poolId - } - } - } -`; - -const isValidCategory = ( - category?: { - color?: string | null; - name?: string | null; - } | null, -): category is { color?: string; name: string } => { - return category != null && typeof category.name === "string"; -}; - -export const getOutcomesForMarkets = async ( - client: GraphQLClient, - markets: { - pool?: { poolId: number } | null; - marketId: number; - marketType: { - categorical?: string | null; - scalar?: (null | string)[] | null; - }; - categories?: { color?: string | null; name?: string | null }[] | null; - }[], -): Promise<{ [marketId: number]: MarketOutcomes }> => { - if (markets.length === 0) { - return {}; - } - const poolIds = markets - .filter((m) => m.pool != null) - .map((m) => m.pool?.poolId) - .sort(); - - const response = await client.request<{ - assets: { - price: number; - assetId: string; - amountInPool: string; - pool: { poolId: number }; - }[]; - }>(assetsQuery, { poolIds }); - - const { assets } = response; - - return markets.reduce((prev, market) => { - const filteredAssets = assets.filter( - (a) => a.pool.poolId === market.pool?.poolId, - ); - - const { marketId, categories } = market; - - const type = - market.marketType.categorical != null ? "categorical" : "scalar"; - - const prevOutcomes = prev[marketId] == null ? [] : [...prev[marketId]]; - - if (filteredAssets.length === 0) { - return { - ...prev, - [marketId]: [...prevOutcomes, ...(categories ?? [])], - }; - } - - const res = { ...prev }; - - let currentOutcomes: MarketOutcomes = []; - - for (const asset of filteredAssets) { - const assetIdJson = JSON.parse(asset.assetId); - let categoryIndex: number; - - if (type === "categorical") { - categoryIndex = assetIdJson["categoricalOutcome"][1]; - } else { - categoryIndex = assetIdJson["scalarOutcome"][1] === "Long" ? 0 : 1; - } - - const category = categories?.[categoryIndex]; - if (!isValidCategory(category)) { - continue; - } - const currentOutcome = { - ...category, - price: asset.price, - assetId: asset.assetId, - amountInPool: asset.amountInPool, - }; - - currentOutcomes = [...currentOutcomes, currentOutcome]; - } - res[marketId] = [...prevOutcomes, ...currentOutcomes]; - - return res; - }, {}); -}; From 0dabf72fe0490ce4b879f085d6f2ff0178cb9c6f Mon Sep 17 00:00:00 2001 From: Tom Robiquet Date: Tue, 13 Feb 2024 10:02:56 +0200 Subject: [PATCH 10/10] misc --- lib/gql/popular-categories.ts | 2 +- lib/hooks/queries/useAccountBonds.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/gql/popular-categories.ts b/lib/gql/popular-categories.ts index 11bf738c6..fca689fdb 100644 --- a/lib/gql/popular-categories.ts +++ b/lib/gql/popular-categories.ts @@ -21,7 +21,7 @@ export const getCategoryCounts = async ( [key: string]: { totalCount: number; }; - }>(`query MyQuery {${queries.join(" ")}}`); + }>(`query CategoryCounts {${queries.join(" ")}}`); const counts = Object.values(response).map((a) => a.totalCount); diff --git a/lib/hooks/queries/useAccountBonds.ts b/lib/hooks/queries/useAccountBonds.ts index dd7afd054..61fdeb668 100644 --- a/lib/hooks/queries/useAccountBonds.ts +++ b/lib/hooks/queries/useAccountBonds.ts @@ -76,6 +76,7 @@ export const useAccountBonds = (address?: string) => { { keepPreviousData: true, enabled: Boolean(sdk && isIndexedSdk(sdk) && address), + staleTime: 100_000, }, );