Skip to content

Commit

Permalink
chore: pulled dev and solved conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
UrbanWill committed Dec 18, 2024
2 parents 5cf6879 + 66a31f4 commit 7add807
Show file tree
Hide file tree
Showing 95 changed files with 2,861 additions and 1,211 deletions.
5 changes: 5 additions & 0 deletions .changeset/four-kids-wink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@talismn/icons": patch
---

feat: added TalismanDeadHandIcon
5 changes: 5 additions & 0 deletions .changeset/hip-windows-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@talismn/balances": minor
---

update to new tokenRates shape
5 changes: 5 additions & 0 deletions .changeset/mean-ducks-thank.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@talismn/chaindata-provider": patch
---

Update init data
5 changes: 5 additions & 0 deletions .changeset/old-gorillas-compete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@talismn/token-rates": major
---

BREAKING - add market cap and 24h change
5 changes: 5 additions & 0 deletions .changeset/slimy-beers-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@talismn/chaindata-provider": patch
---

Update init data
5 changes: 5 additions & 0 deletions .changeset/thirty-crabs-cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@talismn/balances": minor
---

subtensor hotkey in balance meta
5 changes: 5 additions & 0 deletions .changeset/thirty-elephants-breathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@talismn/util": minor
---

formatPrice utility
4 changes: 3 additions & 1 deletion apps/extension/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "extension",
"version": "2.2.0",
"version": "2.3.0",
"private": true,
"license": "GPL-3.0-or-later",
"dependencies": {
Expand Down Expand Up @@ -47,6 +47,7 @@
"@talismn/token-rates": "workspace:*",
"@talismn/util": "workspace:*",
"@tanstack/react-query": "5.59.16",
"@tanstack/react-virtual": "^3.11.1",
"@types/blueimp-md5": "2.18.2",
"@types/chrome": "0.0.279",
"@types/color": "3.0.6",
Expand All @@ -70,6 +71,7 @@
"bignumber.js": "^9.1.2",
"blueimp-md5": "2.19.0",
"buffer": "^6.0.3",
"chart.js": "^4.4.7",
"check-password-strength": "^2.0.10",
"date-fns": "^4.1.0",
"dcent-web-connector": "^0.16.0",
Expand Down
40 changes: 25 additions & 15 deletions apps/extension/src/@talisman/components/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,53 @@
import { ErrorBoundary as SentryErrorBoundary } from "@sentry/react"
import { TalismanDeadHandIcon } from "@talismn/icons"
import { DexieError } from "dexie"
import { FC, ReactNode, useCallback } from "react"
import { Button } from "talisman-ui"

import { DEBUG } from "@extension/shared"
import STATIC from "@talisman/theme/images/hand_open_static_dark.gif"
import { DEBUG, DISCORD_TALISMAN_URL } from "@extension/shared"

const ErrorMessage: FC<{ error: unknown }> = ({ error }) => {
const isDbVersionError = (error as DexieError)?.inner?.name === "VersionError"
const canClearDatabases = DEBUG && isDbVersionError
const errorMessage = isDbVersionError
? "Invalid database version."
: "Sorry, an error occurred in Talisman."

const clearDatabases = useCallback(() => {
indexedDB.deleteDatabase("Talisman")
indexedDB.deleteDatabase("TalismanBalances")
indexedDB.deleteDatabase("TalismanChaindata")
indexedDB.deleteDatabase("TalismanConnectionMeta")
alert("Databases cleared. Please click OK for Talisman to reinitialize.")
alert("Databases cleared. Please click OK for Talisman to reinitialise.")
chrome.runtime.reload()
}, [])

return (
<section className="max-w-screen text-body-secondary mx-auto flex h-[60rem] max-h-screen w-[40rem] flex-col overflow-hidden p-10 text-center">
<div className="flex flex-grow flex-col justify-center">
<h1 className="m-0 text-3xl font-bold">Oops !</h1>
<div>
<img className="inline-block" src={STATIC} alt="Talisman Hand logo" />
<div className="flex w-full flex-grow flex-col items-center justify-center gap-16">
<h1 className="m-0 text-3xl font-bold">Oops!</h1>
<TalismanDeadHandIcon className="text-alert-error text-[20rem]" />
<div className="flex flex-col gap-2">
<div>{errorMessage}</div>
{!canClearDatabases && (
<a
className="text-primary/80 hover:text-primary focus:text-primary"
href={DISCORD_TALISMAN_URL}
target="_blank"
rel="noreferrer noopener"
>
Contact us on Discord for support.
</a>
)}
</div>
{isDbVersionError ? (
<p>Invalid database version.</p>
) : (
<p>Sorry, an error occured in Talisman.</p>
)}
</div>
<div className="flex w-full shrink-0 flex-col gap-4">
{DEBUG && isDbVersionError && (
<Button className="w-full" onClick={clearDatabases}>
{canClearDatabases && (
<Button fullWidth color="red" onClick={clearDatabases}>
Clear local databases
</Button>
)}
<Button className="!w-full" primary onClick={() => window.close()}>
<Button fullWidth onClick={() => window.close()}>
Close
</Button>
</div>
Expand Down
43 changes: 43 additions & 0 deletions apps/extension/src/@talisman/components/FallbackErrorBoundary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { log } from "extension-shared"
import { Component, ErrorInfo, ReactNode } from "react"

interface FallbackErrorBoundaryProps {
children: ReactNode
fallback: ReactNode
}

interface FallbackErrorBoundaryState {
hasError: boolean
}

/**
* Error boundary that catches errors in its children and renders a fallback UI.
* Use this if you don't want to use the Sentry error boundary.
*/
export class FallbackErrorBoundary extends Component<
FallbackErrorBoundaryProps,
FallbackErrorBoundaryState
> {
constructor(props: FallbackErrorBoundaryProps) {
super(props)
this.state = { hasError: false }
}

static getDerivedStateFromError(_: Error): FallbackErrorBoundaryState {
// Update state so the next render will show the fallback UI.
return { hasError: true }
}

componentDidCatch(error: Error, info: ErrorInfo): void {
log.warn("FallbackErrorBoundary caught an error", { error, info })
}

render() {
if (this.state.hasError) {
// Render the provided fallback UI
return this.props.fallback
}

return this.props.children
}
}
18 changes: 17 additions & 1 deletion apps/extension/src/@talisman/components/ScrollContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { classNames } from "@talismn/util"
import { forwardRef, RefObject, useEffect, useMemo, useRef, useState } from "react"

import { provideContext } from "@talisman/util/provideContext"

type ScrollContainerProps = {
className?: string
children?: React.ReactNode
Expand Down Expand Up @@ -67,7 +69,7 @@ export const ScrollContainer = forwardRef<HTMLDivElement, ScrollContainerProps>(
innerClassName,
)}
>
{children}
<ScrollContainerProvider refContainer={refDiv}>{children}</ScrollContainerProvider>
</div>
<div
className={classNames(
Expand All @@ -86,3 +88,17 @@ export const ScrollContainer = forwardRef<HTMLDivElement, ScrollContainerProps>(
},
)
ScrollContainer.displayName = "ScrollContainer"

const useScrollContainerProvider = ({
refContainer,
}: {
refContainer: RefObject<HTMLDivElement>
}) => {
return refContainer
}

const [ScrollContainerProvider, useScrollContainer] = provideContext(useScrollContainerProvider)

// this hook will provite a way for its children to access the ref of the scrollable element
// mainly useful when using a virtualizer or other scroll related libraries
export { useScrollContainer }
2 changes: 1 addition & 1 deletion apps/extension/src/ui/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const api: MessageTypes = {
changePassword: (currentPw, newPw, newPwConfirm) =>
messageService.sendMessage("pri(app.changePassword)", { currentPw, newPw, newPwConfirm }),
changePasswordSubscribe: (currentPw, newPw, newPwConfirm, cb) =>
messageService.sendMessage(
messageService.subscribe(
"pri(app.changePassword.subscribe)",
{ currentPw, newPw, newPwConfirm },
cb,
Expand Down
2 changes: 1 addition & 1 deletion apps/extension/src/ui/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default interface MessageTypes {
newPw: string,
newPwConfirm: string,
cb: (val: ChangePasswordStatusUpdate) => void,
) => Promise<boolean>
) => UnsubscribeFn
checkPassword: (password: string) => Promise<boolean>
authStatus: () => Promise<LoggedinType>
authStatusSubscribe: (cb: (val: LoggedinType) => void) => UnsubscribeFn
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { Token } from "@talismn/chaindata-provider"
import { Token, TokenId } from "@talismn/chaindata-provider"
import { SendIcon } from "@talismn/icons"
import { t } from "i18next"
import { uniq } from "lodash"
import { FC, useEffect, useMemo } from "react"
import { useTranslation } from "react-i18next"
import { useParams } from "react-router-dom"
import { Tooltip, TooltipContent, TooltipTrigger } from "talisman-ui"

import { Balances } from "@extension/core"
import { Breadcrumb } from "@talisman/components/Breadcrumb"
import { NavigateWithQuery } from "@talisman/components/NavigateWithQuery"
import { Fiat } from "@ui/domains/Asset/Fiat"
import { TokenLogo } from "@ui/domains/Asset/TokenLogo"
import { AssetPriceChart } from "@ui/domains/Asset/AssetPriceChart"
import { DashboardAssetDetails } from "@ui/domains/Portfolio/AssetDetails"
import { DashboardPortfolioHeader } from "@ui/domains/Portfolio/DashboardPortfolioHeader"
import { PortfolioToolbarButton } from "@ui/domains/Portfolio/PortfolioToolbarButton"
import { Statistics } from "@ui/domains/Portfolio/Statistics"
import { useDisplayBalances } from "@ui/domains/Portfolio/useDisplayBalances"
Expand All @@ -23,7 +23,6 @@ import {
import { useAnalytics } from "@ui/hooks/useAnalytics"
import { useNavigateWithQuery } from "@ui/hooks/useNavigateWithQuery"
import { useSendFundsPopup } from "@ui/hooks/useSendFundsPopup"
import { useUniswapV2LpTokenTotalValueLocked } from "@ui/hooks/useUniswapV2LpTokenTotalValueLocked"
import { usePortfolio, useSetting } from "@ui/state"

const HeaderRow: FC<{
Expand All @@ -33,6 +32,8 @@ const HeaderRow: FC<{
const { t } = useTranslation()
const canHaveLockedState = Boolean(token?.chain?.id)

if (summary.totalTokens.isZero()) return null

return (
<div className="text-body-secondary bg-grey-850 rounded p-8 text-left text-base">
<div className="grid grid-cols-[40%_30%_30%]">
Expand Down Expand Up @@ -103,43 +104,24 @@ const SendFundsButton: FC<{ symbol: string }> = ({ symbol }) => {
}

const TokenBreadcrumb: FC<{
balances: Balances
symbol: string
token: Token | undefined
rate: number | null | undefined
}> = ({ balances, symbol, token, rate }) => {
}> = ({ symbol }) => {
const { t } = useTranslation()

const navigate = useNavigateWithQuery()

const isUniswapV2LpToken = token?.type === "evm-uniswapv2"
const tvl = useUniswapV2LpTokenTotalValueLocked(token, rate, balances)

const items = useMemo(() => {
return [
{
label: t("All Tokens"),
onClick: () => navigate("/portfolio/tokens"),
},
{
label: (
<div className="flex items-center gap-2">
<TokenLogo tokenId={token?.id} className="text-md" />
<div className="text-body font-bold">{token?.symbol ?? symbol}</div>
{isUniswapV2LpToken && typeof tvl === "number" && (
<div className="text-body-secondary whitespace-nowrap">
<Fiat amount={tvl} /> <span className="text-tiny">TVL</span>
</div>
)}
{!isUniswapV2LpToken && typeof rate === "number" && (
<Fiat amount={rate} className="text-body-secondary" />
)}
</div>
),
label: <div className="text-body font-bold">{symbol}</div>,
onClick: undefined,
},
]
}, [t, token?.id, token?.symbol, symbol, isUniswapV2LpToken, tvl, rate, navigate])
}, [t, symbol, navigate])

return (
<div className="flex h-20 items-center justify-between">
Expand All @@ -149,10 +131,9 @@ const TokenBreadcrumb: FC<{
)
}

export const PortfolioAsset = () => {
const usePortfolioAsset = () => {
const { symbol } = useParams()
const { allBalances } = usePortfolio()
const { pageOpenEvent } = useAnalytics()
const [isTestnet] = useSetting("useTestnets")

const balances = useMemo(
Expand All @@ -165,6 +146,13 @@ export const PortfolioAsset = () => {
const { token, rate, summary } = useTokenBalancesSummary(balances)
const balancesToDisplay = useDisplayBalances(balances)

return { symbol, token, rate, balances, balancesToDisplay, summary }
}

export const PortfolioAsset = () => {
const { symbol, token, balancesToDisplay, summary } = usePortfolioAsset()
const { pageOpenEvent } = useAnalytics()

useEffect(() => {
pageOpenEvent("portfolio asset", { symbol })
}, [pageOpenEvent, symbol])
Expand All @@ -173,9 +161,25 @@ export const PortfolioAsset = () => {

return (
<>
<TokenBreadcrumb token={token} rate={rate} balances={balances} symbol={symbol} />
<TokenBreadcrumb symbol={symbol} />
<HeaderRow token={token} summary={summary} />
<DashboardAssetDetails balances={balancesToDisplay} symbol={symbol} />
</>
)
}

export const PortfolioAssetHeader = () => {
const { balances } = usePortfolioAsset()

// all tokenIds that match the symbol and have a coingeckoId
const tokenIds = useMemo(() => {
return uniq(balances.each.filter((b) => !!b.token?.coingeckoId).map((b) => b.token?.id)).filter(
Boolean,
) as TokenId[]
}, [balances])

// no chart to display, use default header
if (!tokenIds.length) return <DashboardPortfolioHeader />

return <AssetPriceChart tokenIds={tokenIds} variant="large" />
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,14 @@ const PortfolioAccountCheck: FC<PropsWithChildren> = ({ children }) => {
}

export const PortfolioLayout: FC<
PropsWithChildren & { toolbar?: ReactNode; isRampRoute: boolean }
> = ({ toolbar, isRampRoute, children }) => {
PropsWithChildren & { toolbar?: ReactNode; header?: ReactNode; isRampRoute?: boolean }
> = ({ header, isRampRoute, toolbar, children }) => {
return (
<div className="relative flex w-full flex-col gap-6 pb-12">
<Suspense
fallback={<SuspenseTracker name="DashboardPortfolioLayout.PortfolioAccountCheck" />}
>
{!isRampRoute && <DashboardPortfolioHeader />}
{!isRampRoute && (header ?? <DashboardPortfolioHeader />)}
<PortfolioAccountCheck>
<div className="flex h-16 w-full items-center justify-between gap-8 overflow-hidden">
{!isRampRoute && <PortfolioTabs className="text-md my-0 h-14 w-auto font-bold" />}
Expand Down
Loading

0 comments on commit 7add807

Please sign in to comment.