Skip to content

Commit

Permalink
Merge pull request #1023 from madfish-solutions/TW-1174-e-delegate-we…
Browse files Browse the repository at this point in the history
…lcome-is-displayed-like-for-undelegated-user-if-a-rpc-request-is-failed

Tw 1174 Use TZKT for getting a delegate if possible
  • Loading branch information
lourenc authored Dec 5, 2023
2 parents 7161eb9 + 6563f36 commit 03e4567
Show file tree
Hide file tree
Showing 13 changed files with 407 additions and 65 deletions.
6 changes: 6 additions & 0 deletions public/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,12 @@
"tryAgain": {
"message": "Try again"
},
"errorGettingBakerAddressMessageOnline": {
"message": "Failed to get baker's address. Please, reload the page and try again."
},
"errorGettingBakerAddressMessage": {
"message": "Failed to get baker's address. Please, check your internet connection and try again."
},
"tezosMainnet": {
"message": "Tezos Mainnet",
"description": "Mainnet = main network"
Expand Down
52 changes: 27 additions & 25 deletions src/app/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ import React, { Component, ErrorInfo } from 'react';
import classNames from 'clsx';

import { ReactComponent as DangerIcon } from 'app/icons/danger.svg';
import { T } from 'lib/i18n';
import { t, T } from 'lib/i18n';
import { getOnlineStatus } from 'lib/temple/front';

interface ErrorBoundaryProps extends React.PropsWithChildren {
className?: string;
whileMessage?: string;
}

export class BoundaryError extends Error {
constructor(public readonly message: string, public readonly beforeTryAgain: EmptyFn) {
super(message);
}
}

type ErrorBoundaryState = {
error: Error | null;
};
Expand All @@ -33,37 +40,36 @@ export default class ErrorBoundary extends Component<ErrorBoundaryProps> {
});
}

tryAgain() {
async tryAgain() {
const { error } = this.state;
if (error instanceof BoundaryError) {
error.beforeTryAgain();
}
this.setState({ error: null });
}

getDefaultErrorMessage() {
const { whileMessage } = this.props;
const online = getOnlineStatus();
const firstPart = whileMessage ? t('smthWentWrongWhile', [whileMessage]) : t('smthWentWrong');

return online ? firstPart : [firstPart, t('mayHappenBecauseYouAreOffline')].join('. ');
}

render() {
if (this.state.error) {
const online = getOnlineStatus();
const { className, children } = this.props;
const { error } = this.state;

if (error) {
return (
<div className={classNames('w-full', 'flex items-center justify-center', this.props.className)}>
<div className={classNames('w-full', 'flex items-center justify-center', className)}>
<div className={classNames('max-w-xs', 'p-4', 'flex flex-col items-center', 'text-red-600')}>
<DangerIcon className="h-16 w-auto stroke-current" />

<T id="oops">{message => <h2 className="mb-1 text-2xl">{message}</h2>}</T>

<p className="mb-4 text-sm opacity-90 text-center font-light">
{this.props.whileMessage ? (
<T id="smthWentWrongWhile" substitutions={this.props.whileMessage} />
) : (
<T id="smthWentWrong" />
)}
{!online && (
<T id="mayHappenBecauseYouAreOffline">
{message => (
<>
{'. '}
{message}
</>
)}
</T>
)}
{error instanceof BoundaryError ? error.message : this.getDefaultErrorMessage()}
</p>

<T id="tryAgain">
Expand Down Expand Up @@ -92,10 +98,6 @@ export default class ErrorBoundary extends Component<ErrorBoundaryProps> {
);
}

return this.props.children;
return children;
}
}

function getOnlineStatus() {
return typeof navigator !== 'undefined' && typeof navigator.onLine === 'boolean' ? navigator.onLine : true;
}
28 changes: 16 additions & 12 deletions src/app/pages/Home/ContentSection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FC, ReactNode, Suspense, useCallback, useMemo, useRef } from 'react';
import React, { FC, memo, Suspense, useCallback, useMemo, useRef } from 'react';

import clsx from 'clsx';

Expand Down Expand Up @@ -33,7 +33,7 @@ interface TabData {
whileMessageI18nKey?: TID;
}

export const ContentSection: FC<Props> = ({ assetSlug, className }) => {
export const ContentSection = memo<Props>(({ assetSlug, className }) => {
const { fullPage } = useAppEnv();
const tabSlug = useTabSlug();

Expand Down Expand Up @@ -115,25 +115,29 @@ export const ContentSection: FC<Props> = ({ assetSlug, className }) => {
<div className={clsx('-mx-4 shadow-top-light', fullPage && 'rounded-t-md', className)}>
<TabsBar ref={tabBarElemRef} tabs={tabs} activeTabName={name} />

<SuspenseContainer whileMessage={whileMessageI18nKey ? t(whileMessageI18nKey) : 'displaying tab'}>
{Component && <Component />}
</SuspenseContainer>
<ContentContainer
key={tabSlug ?? 'tokens'}
ContentComponent={Component}
whileMessage={whileMessageI18nKey ? t(whileMessageI18nKey) : 'displaying tab'}
/>
</div>
);
};
});

interface SuspenseContainerProps extends PropsWithChildren {
interface ContentContainerProps {
whileMessage: string;
fallback?: ReactNode;
ContentComponent: React.FC | React.ExoticComponent;
}

const SuspenseContainer: FC<SuspenseContainerProps> = ({ whileMessage, fallback = <SpinnerSection />, children }) => (
const ContentContainer = memo<ContentContainerProps>(({ whileMessage, ContentComponent }) => (
<ErrorBoundary whileMessage={whileMessage}>
<Suspense fallback={fallback}>{children}</Suspense>
<Suspense fallback={<SpinnerSection />}>
<ContentComponent />
</Suspense>
</ErrorBoundary>
);
));

const SpinnerSection: FC = () => (
const SpinnerSection = () => (
<div className="flex justify-center my-12">
<Spinner theme="gray" className="w-20" />
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/Home/OtherComponents/BakingSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const links = [

const BakingSection = memo(() => {
const acc = useAccount();
const { data: myBakerPkh } = useDelegate(acc.publicKeyHash);
const { data: myBakerPkh } = useDelegate(acc.publicKeyHash, true, false);
const canDelegate = acc.type !== TempleAccountType.WatchOnly;
const chainId = useChainId(true);
const { isDcpNetwork } = useGasToken();
Expand Down
12 changes: 8 additions & 4 deletions src/lib/apis/tzkt/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ import {
allInt32ParameterKeys,
TzktGetRewardsParams,
TzktGetRewardsResponse,
TzktRelatedContract
TzktRelatedContract,
TzktAccount
} from './types';

const TZKT_API_BASE_URLS = {
[TempleChainId.Mainnet]: 'https://api.tzkt.io/v1',
[TempleChainId.Jakartanet]: 'https://api.jakartanet.tzkt.io/v1',
[TempleChainId.Limanet]: 'https://api.limanet.tzkt.io/v1',
[TempleChainId.Mumbai]: 'https://api.mumbainet.tzkt.io/v1',
[TempleChainId.Nairobi]: 'https://api.nairobinet.tzkt.io/v1',
[TempleChainId.Ghostnet]: 'https://api.ghostnet.tzkt.io/v1',
[TempleChainId.Dcp]: 'https://explorer-api.tlnt.net/v1',
[TempleChainId.DcpTest]: 'https://explorer.tlnt.net:8009/v1'
[TempleChainId.DcpTest]: 'https://explorer-api.test.tlnt.net/v1'
};

export type TzktApiChainId = keyof typeof TZKT_API_BASE_URLS;
Expand Down Expand Up @@ -189,3 +190,6 @@ export const fetchAllTokensBalancesFromTzkt = async (selectedRpcUrl: string, acc

return balances;
};

export const getAccountStatsFromTzkt = async (account: string, chainId: TzktApiChainId) =>
fetchGet<TzktAccount>(chainId, `/accounts/${account}`);
3 changes: 3 additions & 0 deletions src/lib/apis/tzkt/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ export type {
TzktAccountToken
} from './types';

export { TzktAccountType } from './types';

export type { TzktApiChainId } from './api';
export {
isKnownChainId,
getAccountStatsFromTzkt,
getDelegatorRewards,
getOneUserContracts,
fetchTzktTokens,
Expand Down
Loading

0 comments on commit 03e4567

Please sign in to comment.