|
|
@@ -3,12 +3,20 @@
|
|
|
import { PlusMinus } from "@phosphor-icons/react/dist/ssr/PlusMinus";
|
|
|
import type { PriceData, PriceComponent } from "@pythnetwork/client";
|
|
|
import { PriceStatus } from "@pythnetwork/client";
|
|
|
+import { DocumentTitle } from "@pythnetwork/component-library/DocumentTitle";
|
|
|
import { Skeleton } from "@pythnetwork/component-library/Skeleton";
|
|
|
-import type { ReactNode } from "react";
|
|
|
import { useMemo } from "react";
|
|
|
import { useDateFormatter } from "react-aria";
|
|
|
|
|
|
import styles from "./index.module.scss";
|
|
|
+import type {
|
|
|
+ LiveAggregatedPriceOrConfidenceProps,
|
|
|
+ LiveComponentConfidenceProps,
|
|
|
+ LiveComponentValueProps,
|
|
|
+ LivePriceOrConfidenceProps,
|
|
|
+ LiveValueProps,
|
|
|
+ PriceProps,
|
|
|
+} from "./types";
|
|
|
import {
|
|
|
useLivePriceComponent,
|
|
|
useLivePriceData,
|
|
|
@@ -21,11 +29,7 @@ export const SKELETON_WIDTH = 20;
|
|
|
export const LivePrice = ({
|
|
|
publisherKey,
|
|
|
...props
|
|
|
-}: {
|
|
|
- feedKey: string;
|
|
|
- publisherKey?: string | undefined;
|
|
|
- cluster: Cluster;
|
|
|
-}) =>
|
|
|
+}: LivePriceOrConfidenceProps) =>
|
|
|
publisherKey === undefined ? (
|
|
|
<LiveAggregatePrice {...props} />
|
|
|
) : (
|
|
|
@@ -35,16 +39,15 @@ export const LivePrice = ({
|
|
|
const LiveAggregatePrice = ({
|
|
|
feedKey,
|
|
|
cluster,
|
|
|
-}: {
|
|
|
- feedKey: string;
|
|
|
- cluster: Cluster;
|
|
|
-}) => {
|
|
|
+ ...rest
|
|
|
+}: LiveAggregatedPriceOrConfidenceProps) => {
|
|
|
const { prev, current } = useLivePriceData(cluster, feedKey);
|
|
|
if (current === undefined) {
|
|
|
- return <Price />;
|
|
|
+ return <Price {...rest} />;
|
|
|
} else if (current.status === PriceStatus.Trading) {
|
|
|
return (
|
|
|
<Price
|
|
|
+ {...rest}
|
|
|
current={current.price}
|
|
|
prev={prev?.price}
|
|
|
exponent={current.exponent}
|
|
|
@@ -52,7 +55,11 @@ const LiveAggregatePrice = ({
|
|
|
);
|
|
|
} else {
|
|
|
return (
|
|
|
- <Price current={current.previousPrice} exponent={current.exponent} />
|
|
|
+ <Price
|
|
|
+ {...rest}
|
|
|
+ current={current.previousPrice}
|
|
|
+ exponent={current.exponent}
|
|
|
+ />
|
|
|
);
|
|
|
}
|
|
|
};
|
|
|
@@ -84,30 +91,36 @@ const Price = ({
|
|
|
prev,
|
|
|
current,
|
|
|
exponent,
|
|
|
-}: {
|
|
|
- prev?: number | undefined;
|
|
|
- current?: number | undefined;
|
|
|
- exponent?: number | undefined;
|
|
|
-}) =>
|
|
|
- current === undefined ? (
|
|
|
- <Skeleton width={SKELETON_WIDTH} />
|
|
|
- ) : (
|
|
|
- <span
|
|
|
- className={styles.price}
|
|
|
- data-direction={prev ? getChangeDirection(prev, current) : "flat"}
|
|
|
- >
|
|
|
- <FormattedPriceValue n={current} exponent={exponent} />
|
|
|
- </span>
|
|
|
+ pageTitlePrecision,
|
|
|
+ updatePageTitle = false,
|
|
|
+}: PriceProps) => {
|
|
|
+ if (!current) return <Skeleton width={SKELETON_WIDTH} />;
|
|
|
+
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ {updatePageTitle && (
|
|
|
+ <DocumentTitle
|
|
|
+ prefix={
|
|
|
+ typeof pageTitlePrecision === "number"
|
|
|
+ ? current.toFixed(pageTitlePrecision)
|
|
|
+ : String(current)
|
|
|
+ }
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ <span
|
|
|
+ className={styles.price}
|
|
|
+ data-direction={prev ? getChangeDirection(prev, current) : "flat"}
|
|
|
+ >
|
|
|
+ <FormattedPriceValue n={current} exponent={exponent} />
|
|
|
+ </span>
|
|
|
+ </>
|
|
|
);
|
|
|
+};
|
|
|
|
|
|
export const LiveConfidence = ({
|
|
|
publisherKey,
|
|
|
...props
|
|
|
-}: {
|
|
|
- feedKey: string;
|
|
|
- publisherKey?: string | undefined;
|
|
|
- cluster: Cluster;
|
|
|
-}) =>
|
|
|
+}: LivePriceOrConfidenceProps) =>
|
|
|
publisherKey === undefined ? (
|
|
|
<LiveAggregateConfidence {...props} />
|
|
|
) : (
|
|
|
@@ -117,10 +130,7 @@ export const LiveConfidence = ({
|
|
|
const LiveAggregateConfidence = ({
|
|
|
feedKey,
|
|
|
cluster,
|
|
|
-}: {
|
|
|
- feedKey: string;
|
|
|
- cluster: Cluster;
|
|
|
-}) => {
|
|
|
+}: LiveAggregatedPriceOrConfidenceProps) => {
|
|
|
const { current } = useLivePriceData(cluster, feedKey);
|
|
|
return (
|
|
|
<Confidence
|
|
|
@@ -139,11 +149,7 @@ const LiveComponentConfidence = ({
|
|
|
feedKey,
|
|
|
publisherKey,
|
|
|
cluster,
|
|
|
-}: {
|
|
|
- feedKey: string;
|
|
|
- publisherKey: string;
|
|
|
- cluster: Cluster;
|
|
|
-}) => {
|
|
|
+}: LiveComponentConfidenceProps) => {
|
|
|
const { current } = useLivePriceComponent(cluster, feedKey, publisherKey);
|
|
|
const { current: priceData } = useLivePriceData(cluster, feedKey);
|
|
|
return (
|
|
|
@@ -220,13 +226,6 @@ export const LiveLastUpdated = ({
|
|
|
return formattedTimestamp ?? <Skeleton width={SKELETON_WIDTH} />;
|
|
|
};
|
|
|
|
|
|
-type LiveValueProps<T extends keyof PriceData> = {
|
|
|
- field: T;
|
|
|
- feedKey: string;
|
|
|
- defaultValue?: ReactNode | undefined;
|
|
|
- cluster: Cluster;
|
|
|
-};
|
|
|
-
|
|
|
export const LiveValue = <T extends keyof PriceData>({
|
|
|
feedKey,
|
|
|
field,
|
|
|
@@ -249,14 +248,6 @@ export const LiveValue = <T extends keyof PriceData>({
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-type LiveComponentValueProps<T extends keyof PriceComponent["latest"]> = {
|
|
|
- field: T;
|
|
|
- feedKey: string;
|
|
|
- publisherKey: string;
|
|
|
- defaultValue?: ReactNode | undefined;
|
|
|
- cluster: Cluster;
|
|
|
-};
|
|
|
-
|
|
|
export const LiveComponentValue = <T extends keyof PriceComponent["latest"]>({
|
|
|
feedKey,
|
|
|
field,
|