Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@
"localhost",
"arbitrum",
"arbitrum_sepolia",
"arbitrum_nova",
"base",
"blackfort_testnet",
"celo",
Expand Down
2 changes: 2 additions & 0 deletions configs/envs/.env.mega_eth
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ NEXT_PUBLIC_MARKETPLACE_CATEGORIES_URL=https://raw.githubusercontent.com/blocksc
NEXT_PUBLIC_MARKETPLACE_ENABLED=true
NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM=https://airtable.com/appiy5yijZpMMSKjT/shr6uMGPKjj1DK7NL
NEXT_PUBLIC_MARKETPLACE_SUGGEST_IDEAS_FORM=https://airtable.com/appiy5yijZpMMSKjT/pag3t82DUCyhGRZZO/form
NEXT_PUBLIC_MEGA_ETH_SOCKET_URL_METRICS=wss://testnetv2-dashboard.megaeth.com/metrics
NEXT_PUBLIC_MEGA_ETH_SOCKET_URL_RPC=wss://megaeth-testnet-v2.blockscout.com/api/v2/proxy/3rdparty/ws_megaeth_testnet_2
NEXT_PUBLIC_METADATA_SERVICE_API_HOST=https://metadata.services.blockscout.com
NEXT_PUBLIC_MIXPANEL_CONFIG_OVERRIDES={"record_sessions_percent": 0.5,"record_heatmap_data": true}
NEXT_PUBLIC_NETWORK_CURRENCY_DECIMALS=18
Expand Down
18 changes: 17 additions & 1 deletion lib/contexts/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ interface TSettingsContext {
toggleAddressFormat: () => void;
timeFormat: TimeFormat;
toggleTimeFormat: () => void;
isLocalTime: boolean;
toggleIsLocalTime: () => void;
}

export const SettingsContext = React.createContext<TSettingsContext | null>(null);
Expand All @@ -32,6 +34,10 @@ export function SettingsContextProvider({ children }: SettingsProviderProps) {
cookies.get(cookies.NAMES.TIME_FORMAT, appCookies) as TimeFormat || 'relative',
);

const [ isLocalTime, setIsLocalTime ] = React.useState<boolean>(
(cookies.get(cookies.NAMES.LOCAL_TIME, appCookies) ?? 'true') === 'true',
);

const toggleAddressFormat = React.useCallback(() => {
setAddressFormat(prev => {
const nextValue = prev === 'base16' ? 'bech32' : 'base16';
Expand All @@ -48,14 +54,24 @@ export function SettingsContextProvider({ children }: SettingsProviderProps) {
});
}, []);

const toggleIsLocalTime = React.useCallback(() => {
setIsLocalTime(prev => {
const nextValue = !prev;
cookies.set(cookies.NAMES.LOCAL_TIME, nextValue ? 'true' : 'false');
return nextValue;
});
}, []);

const value = React.useMemo(() => {
return {
addressFormat,
toggleAddressFormat,
timeFormat,
toggleTimeFormat,
isLocalTime,
toggleIsLocalTime,
};
}, [ addressFormat, toggleAddressFormat, timeFormat, toggleTimeFormat ]);
}, [ addressFormat, toggleAddressFormat, timeFormat, toggleTimeFormat, isLocalTime, toggleIsLocalTime ]);

return (
<SettingsContext.Provider value={ value }>
Expand Down
1 change: 1 addition & 0 deletions lib/cookies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export enum NAMES {
ADDRESS_IDENTICON_TYPE = 'address_identicon_type',
ADDRESS_FORMAT = 'address_format',
TIME_FORMAT = 'time_format',
LOCAL_TIME = 'local_time',
INDEXING_ALERT = 'indexing_alert',
ADBLOCK_DETECTED = 'adblock_detected',
MIXPANEL_DEBUG = '_mixpanel_debug',
Expand Down
7 changes: 7 additions & 0 deletions lib/date/dayjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import localizedFormat from 'dayjs/plugin/localizedFormat';
import minMax from 'dayjs/plugin/minMax';
import relativeTime from 'dayjs/plugin/relativeTime';
import updateLocale from 'dayjs/plugin/updateLocale';
import utc from 'dayjs/plugin/utc';
import weekOfYear from 'dayjs/plugin/weekOfYear';

import { nbsp } from 'toolkit/utils/htmlEntities';
Expand Down Expand Up @@ -34,6 +35,7 @@ dayjs.extend(localizedFormat);
dayjs.extend(duration);
dayjs.extend(weekOfYear);
dayjs.extend(minMax);
dayjs.extend(utc);

dayjs.updateLocale('en', {
formats: {
Expand Down Expand Up @@ -63,3 +65,8 @@ dayjs.updateLocale('en', {
dayjs.locale('en');

export default dayjs;

export const FORMATS = {
// the "lll" format with seconds
lll_s: 'MMM D, YYYY h:mm:ss A',
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions ui/address/contract/info/ContractDetailsInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import type { SmartContract } from 'types/api/contract';
import config from 'configs/app';
import { useMultichainContext } from 'lib/contexts/multichain';
import { CONTRACT_LICENSES } from 'lib/contracts/licenses';
import dayjs from 'lib/date/dayjs';
import { Link } from 'toolkit/chakra/link';
import { getGitHubOwnerAndRepo } from 'ui/contractVerification/utils';
import ContainerWithScrollY from 'ui/shared/ContainerWithScrollY';
import ContractCertifiedLabel from 'ui/shared/ContractCertifiedLabel';
import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TxEntity from 'ui/shared/entities/tx/TxEntity';
import ContractCreationStatus from 'ui/shared/statusTag/ContractCreationStatus';
import Time from 'ui/shared/time/Time';

import ContractSecurityAudits from '../audits/ContractSecurityAudits';
import ContractDetailsInfoItem from './ContractDetailsInfoItem';
Expand Down Expand Up @@ -187,7 +187,7 @@ const ContractDetailsInfo = ({ data, isLoading, addressData }: Props) => {
wordBreak="break-word"
isLoading={ isLoading }
>
{ dayjs(data.verified_at).format('llll') }
<Time timestamp={ data.verified_at } format="lll_s"/>
</ContractDetailsInfoItem>
) }
{ data.file_path && !isStylusContract && (
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions ui/address/mud/AddressMudRecord.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { useRouter } from 'next/router';
import React from 'react';

import useApiQuery from 'lib/api/useApiQuery';
import dayjs from 'lib/date/dayjs';
import getQueryParamString from 'lib/router/getQueryParamString';
import { TableRoot, TableRow, TableCell } from 'toolkit/chakra/table';
import { ContentLoader } from 'toolkit/components/loaders/ContentLoader';
import { TruncatedText } from 'toolkit/components/truncation/TruncatedText';
import DataFetchAlert from 'ui/shared/DataFetchAlert';
import Time from 'ui/shared/time/Time';

import AddressMudBreadcrumbs from './AddressMudBreadcrumbs';
import AddressMudRecordValues from './AddressMudRecordValues';
Expand Down Expand Up @@ -62,7 +62,7 @@ const AddressMudRecord = ({ tableId, recordId, isQueryEnabled = true }: Props) =
<TableCell colSpan={ 2 } fontSize="sm">
<Flex justifyContent="space-between">
<TruncatedText text={ getValueString(data.record.decoded[keyName]) } mr={ 2 }/>
{ index === 0 && <Box color="text.secondary">{ dayjs(data.record.timestamp).format('lll') }</Box> }
{ index === 0 && <Time color="text.secondary" timestamp={ data.record.timestamp }/> }
</Flex>
</TableCell>
</TableRow>
Expand All @@ -79,7 +79,7 @@ const AddressMudRecord = ({ tableId, recordId, isQueryEnabled = true }: Props) =
{ keyName } ({ data.schema.key_types[index] })
</Text>
<Text wordBreak="break-word">{ getValueString(data.record.decoded[keyName]) }</Text>
{ index === 0 && <Box color="text.secondary">{ dayjs(data.record.timestamp).format('lll') }</Box> }
{ index === 0 && <Time color="text.secondary" timestamp={ data.record.timestamp }/> }
</VStack>
)) }
<TableRoot borderRadius="8px" style={{ tableLayout: 'auto' }} width="100%" mt={ 2 } overflow="hidden">
Expand Down
4 changes: 2 additions & 2 deletions ui/address/mud/AddressMudRecordsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type { AddressMudRecords, AddressMudRecordsFilter, AddressMudRecordsSorti
import { route } from 'nextjs-routes';

import capitalizeFirstLetter from 'lib/capitalizeFirstLetter';
import dayjs from 'lib/date/dayjs';
import useIsMobile from 'lib/hooks/useIsMobile';
import { Link } from 'toolkit/chakra/link';
import { TableBody, TableCell, TableColumnHeader, TableHeaderSticky, TableRoot, TableRow } from 'toolkit/chakra/table';
Expand All @@ -16,6 +15,7 @@ import { Tooltip } from 'toolkit/chakra/tooltip';
import { middot } from 'toolkit/utils/htmlEntities';
import CopyToClipboard from 'ui/shared/CopyToClipboard';
import IconSvg from 'ui/shared/IconSvg';
import Time from 'ui/shared/time/Time';

import AddressMudRecordsKeyFilter from './AddressMudRecordsKeyFilter';
import { getNameTypeText, getValueString } from './utils';
Expand Down Expand Up @@ -213,7 +213,7 @@ const AddressMudRecordsTable = ({
{ values.map((valName) =>
<TableCell key={ valName } { ...tdStyles }>{ getValueString(item.decoded[valName]) }</TableCell>) }
{ hasCut && !isOpened && <TableCell width={ `${ CUT_COL_WIDTH }px ` }></TableCell> }
<TableCell { ...tdStyles } color="text.secondary" w={ `${ colW }px` }>{ dayjs(item.timestamp).format('lll') }</TableCell>
<TableCell { ...tdStyles } color="text.secondary" w={ `${ colW }px` }><Time timestamp={ item.timestamp }/></TableCell>
{ hasCut && isOpened && <TableCell width={ `${ CUT_COL_WIDTH }px ` }></TableCell> }
</TableRow>
)) }
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions ui/blocks/flashblocks/FlashblocksListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import type { FlashblockItem } from 'types/client/flashblocks';

import { route } from 'nextjs-routes';

import dayjs from 'lib/date/dayjs';
import { Link } from 'toolkit/chakra/link';
import FlashblockEntity from 'ui/shared/entities/flashblock/FlashblockEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import Time from 'ui/shared/time/Time';

interface Props {
data: FlashblockItem;
Expand All @@ -29,7 +29,7 @@ const FlashblocksListItem = ({ data }: Props) => {
{ data.timestamp && (
<Flex columnGap={ 2 }>
<Text fontWeight={ 500 }>Timestamp</Text>
<Text color="text.secondary">{ dayjs(data.timestamp).format('DD MMM, HH:mm:ss.SSS') }</Text>
<Time color="text.secondary" timestamp={ data.timestamp } format="DD MMM, HH:mm:ss.SSS"/>
</Flex>
) }
<Flex columnGap={ 2 }>
Expand Down
4 changes: 2 additions & 2 deletions ui/blocks/flashblocks/FlashblocksTableItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import type { FlashblockItem } from 'types/client/flashblocks';

import { route } from 'nextjs-routes';

import dayjs from 'lib/date/dayjs';
import { Link } from 'toolkit/chakra/link';
import { TableCell, TableRow } from 'toolkit/chakra/table';
import FlashblockEntity from 'ui/shared/entities/flashblock/FlashblockEntity';
import Time from 'ui/shared/time/Time';

interface Props {
data: FlashblockItem;
Expand All @@ -28,7 +28,7 @@ const FlashblocksTableItem = ({ data }: Props) => {
) : (
<Text color="text.secondary">N/A</Text>
) }
{ data.timestamp && <Text color="text.secondary">{ dayjs(data.timestamp).format('DD MMM, HH:mm:ss.SSS') }</Text> }
{ data.timestamp && <Time color="text.secondary" timestamp={ data.timestamp } format="DD MMM, HH:mm:ss.SSS"/> }
</HStack>
</TableCell>
<TableCell isNumeric>
Expand Down
12 changes: 8 additions & 4 deletions ui/epochs/EpochsListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import React from 'react';

import type { CeloEpochListItem } from 'types/api/epochs';

import dayjs from 'lib/date/dayjs';
import { Skeleton } from 'toolkit/chakra/skeleton';
import DetailedInfoTimestamp from 'ui/shared/DetailedInfo/DetailedInfoTimestamp';
import EpochEntity from 'ui/shared/entities/epoch/EpochEntity';
import ListItemMobile from 'ui/shared/ListItemMobile/ListItemMobile';
import CeloEpochStatus from 'ui/shared/statusTag/CeloEpochStatus';
import TextSeparator from 'ui/shared/TextSeparator';
import Time from 'ui/shared/time/Time';
import NativeCoinValue from 'ui/shared/value/NativeCoinValue';

interface Props {
Expand All @@ -24,9 +26,11 @@ const EpochsListItem = ({ item, isLoading }: Props) => {
<CeloEpochStatus isFinalized={ item.is_finalized } loading={ isLoading }/>
</HStack>
{ item.timestamp && (
<HStack minH="30px" gap={ 0 } color="text.secondary" fontWeight={ 400 }>
<DetailedInfoTimestamp timestamp={ item.timestamp } isLoading={ isLoading } noIcon/>
</HStack>
<Skeleton loading={ isLoading } display="flex" alignItems="center" minH="30px" color="text.secondary">
<div>{ dayjs(item.timestamp).fromNow() }</div>
<TextSeparator/>
<Time timestamp={ item.timestamp } format="lll_s"/>
</Skeleton>
) }
<HStack minH="30px">
<Skeleton loading={ isLoading }>Block range</Skeleton>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import AddressEntity from 'ui/shared/entities/address/AddressEntity';
import TokenEntity from 'ui/shared/entities/token/TokenEntity';
import ListItemMobileGrid from 'ui/shared/ListItemMobile/ListItemMobileGrid';
import NumberEntity from 'ui/shared/NumberEntity';
import Time from 'ui/shared/time/Time';

import useRevoke from '../hooks/useRevoke';
import formatAllowance from '../lib/formatAllowance';
Expand Down Expand Up @@ -119,7 +120,7 @@ export default function ApprovalsListItem({
<ListItemMobileGrid.Label isLoading={ isLoading }>Last updated</ListItemMobileGrid.Label>
<ListItemMobileGrid.Value color="inherit">
<Skeleton loading={ isLoading } display="flex" flexDir="column" rowGap={ 2 }>
<Text>{ dayjs(approval.timestamp).format('lll') }</Text>
<Time timestamp={ approval.timestamp }/>
<Text>{ dayjs(approval.timestamp).fromNow() }</Text>
</Skeleton>
</ListItemMobileGrid.Value>
Expand Down
39 changes: 25 additions & 14 deletions ui/megaEth/uptime/UptimeCharts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React from 'react';
import type { AxesConfigFn } from 'toolkit/components/charts/types';
import type { UptimeHistoryFull, UptimeHistoryItem } from 'types/api/megaEth';

import { useSettingsContext } from 'lib/contexts/settings';
import { Heading } from 'toolkit/chakra/heading';
import { ChartWidget } from 'toolkit/components/charts/ChartWidget';
import { DAY, HOUR, SECOND } from 'toolkit/utils/consts';
Expand All @@ -21,14 +22,14 @@ type IntervalId = (typeof INTERVALS)[number]['id'];

const TIME_FORMAT = '%e %b %Y, %H:%M:%S';

const AXES_CONFIG_BASE: AxesConfigFn = ({ isEnlarged, isMobile }) => ({
const AXES_CONFIG_BASE: (isLocalTime: boolean) => AxesConfigFn = (isLocalTime) => ({ isEnlarged, isMobile }) => ({
y: {
scale: { min: 0 },
},
x: {
ticks: isEnlarged && !isMobile ? 8 : 5,
tickFormatter: () => (d: d3.AxisDomain) => {
return d3.timeFormat('%H:%M')(d as Date);
return isLocalTime ? d3.timeFormat('%H:%M')(d as Date) : d3.utcFormat('%H:%M')(d as Date);
},
},
});
Expand Down Expand Up @@ -80,15 +81,17 @@ const UptimeCharts = ({ historyData }: Props) => {
const [ interval, setInterval ] = React.useState<IntervalId>('3h');
const chartsConfig = useChartsConfig();

const { isLocalTime } = useSettingsContext() ?? { isLocalTime: true };

const axesConfig = React.useMemo(() => {
switch (interval) {
case '3h':
case '24h':
return AXES_CONFIG_BASE;
return AXES_CONFIG_BASE(isLocalTime);
case '7d':
return AXES_CONFIG_LONG;
}
}, [ interval ]);
}, [ interval, isLocalTime ]);

const tpsCharts = React.useMemo(() => {
if (!historyData) {
Expand All @@ -111,11 +114,11 @@ const UptimeCharts = ({ historyData }: Props) => {
const items = smoothedData
.map(({ value, timestamp }) => {
const date = new Date(timestamp * SECOND);
// Here and below,
// despite the other charts in the stats page, this one should display dates & time in the local timezone, not UTC.
// This is because it is a "time-based" chart not a "date-based" one.
// That is why we use d3.timeFormat() instead of dayjs.utcFormat() here.
return { date, value: Number(value.toFixed(0)), dateLabel: d3.timeFormat(TIME_FORMAT)(date) };
return {
date,
value: Number(value.toFixed(0)),
dateLabel: isLocalTime ? d3.timeFormat(TIME_FORMAT)(date) : d3.utcFormat(TIME_FORMAT)(date),
};
})
.filter(filterByInterval(interval, now));

Expand All @@ -127,7 +130,7 @@ const UptimeCharts = ({ historyData }: Props) => {
charts: chartsConfig,
},
];
}, [ chartsConfig, historyData, interval ]);
}, [ chartsConfig, historyData, interval, isLocalTime ]);

const gasCharts = React.useMemo(() => {
if (!historyData) {
Expand All @@ -152,7 +155,11 @@ const UptimeCharts = ({ historyData }: Props) => {
const items = smoothedData
.map(({ value, timestamp }) => {
const date = new Date(timestamp * SECOND);
return { date, value: Number((value / 1_000_000).toFixed(2)), dateLabel: d3.timeFormat(TIME_FORMAT)(date) };
return {
date,
value: Number((value / 1_000_000).toFixed(2)),
dateLabel: isLocalTime ? d3.timeFormat(TIME_FORMAT)(date) : d3.utcFormat(TIME_FORMAT)(date),
};
})
.filter(filterByInterval(interval, now));

Expand All @@ -164,7 +171,7 @@ const UptimeCharts = ({ historyData }: Props) => {
charts: chartsConfig,
},
];
}, [ chartsConfig, historyData, interval ]);
}, [ chartsConfig, historyData, interval, isLocalTime ]);

const blockIntervalCharts = React.useMemo(() => {
if (!historyData) {
Expand All @@ -189,7 +196,11 @@ const UptimeCharts = ({ historyData }: Props) => {
const items = smoothedData
.map(({ value, timestamp }) => {
const date = new Date(timestamp * SECOND);
return { date, value: Number(value.toFixed(1)), dateLabel: d3.timeFormat(TIME_FORMAT)(date) };
return {
date,
value: Number(value.toFixed(1)),
dateLabel: isLocalTime ? d3.timeFormat(TIME_FORMAT)(date) : d3.utcFormat(TIME_FORMAT)(date),
};
})
.filter(filterByInterval(interval, now));

Expand All @@ -201,7 +212,7 @@ const UptimeCharts = ({ historyData }: Props) => {
charts: chartsConfig,
},
];
}, [ chartsConfig, historyData, interval ]);
}, [ chartsConfig, historyData, interval, isLocalTime ]);

const handleIntervalChange = React.useCallback((newInterval: IntervalId) => {
setInterval(newInterval);
Expand Down
Loading
Loading