Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev' into epic/safe-proposers
Browse files Browse the repository at this point in the history
  • Loading branch information
usame-algan committed Nov 6, 2024
2 parents 2396942 + d90cbfa commit b5b354d
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 45 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "safe-wallet-web",
"homepage": "https://github.com/safe-global/safe-wallet-web",
"license": "GPL-3.0",
"version": "1.45.2",
"version": "1.45.3",
"type": "module",
"scripts": {
"dev": "next dev",
Expand Down
2 changes: 1 addition & 1 deletion src/components/settings/ProposersList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ const ProposersList = () => {
},
}
})
}, [proposers.data])
}, [isEnabled, proposers.data])

if (!proposers.data?.results) return null

Expand Down
72 changes: 72 additions & 0 deletions src/components/sidebar/IndexingStatus/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Stack, Box, Typography, Tooltip } from '@mui/material'
import { formatDistanceToNow } from 'date-fns'
import { getIndexingStatus } from '@safe-global/safe-gateway-typescript-sdk'
import useAsync from '@/hooks/useAsync'
import useChainId from '@/hooks/useChainId'
import ExternalLink from '@/components/common/ExternalLink'

const STATUS_PAGE = 'https://status.safe.global'
const MAX_SYNC_DELAY = 1000 * 60 * 5 // 5 minutes

const useIndexingStatus = () => {
const chainId = useChainId()

return useAsync(() => {
return getIndexingStatus(chainId)
}, [chainId])
}

const STATUSES = {
synced: {
color: 'success',
text: 'Synced',
},
slow: {
color: 'warning',
text: 'Slow network',
},
outOfSync: {
color: 'error',
text: 'Out of sync',
},
}

const getStatus = (synced: boolean, lastSync: number) => {
let status = STATUSES.outOfSync

if (synced) {
status = STATUSES.synced
} else if (Date.now() - lastSync > MAX_SYNC_DELAY) {
status = STATUSES.slow
}

return status
}

const IndexingStatus = () => {
const [data] = useIndexingStatus()

if (!data) {
return null
}

const status = getStatus(data.synced, data.lastSync)

const time = formatDistanceToNow(data.lastSync, { addSuffix: true })

return (
<Tooltip title={`Last synced with the blockchain ${time}`} placement="right" arrow>
<Stack direction="row" spacing={2} alignItems="center" px={3} py={1.5}>
<Box width={10} height={10} borderRadius="50%" border={`2px solid var(--color-${status.color}-main)`} />

<ExternalLink href={STATUS_PAGE} noIcon flex={1}>
<Typography variant="body2">{status.text}</Typography>
</ExternalLink>

<ExternalLink href={STATUS_PAGE} sx={{ color: 'text.secondary', transform: 'translateY(3px)' }} />
</Stack>
</Tooltip>
)
}

export default IndexingStatus
5 changes: 5 additions & 0 deletions src/components/sidebar/Sidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ChainIndicator from '@/components/common/ChainIndicator'
import SidebarHeader from '@/components/sidebar/SidebarHeader'
import SidebarNavigation from '@/components/sidebar/SidebarNavigation'
import SidebarFooter from '@/components/sidebar/SidebarFooter'
import IndexingStatus from '@/components/sidebar/IndexingStatus'

import css from './styles.module.css'
import { trackEvent, OVERVIEW_EVENTS } from '@/services/analytics'
Expand Down Expand Up @@ -48,6 +49,10 @@ const Sidebar = (): ReactElement => {

{/* What's new + Need help? */}
<SidebarFooter />

<Divider flexItem />

<IndexingStatus />
</div>

<Drawer variant="temporary" anchor="left" open={isDrawerOpen} onClose={onDrawerToggle}>
Expand Down
28 changes: 19 additions & 9 deletions src/features/targetedOutreach/components/OutreachPopup/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useCreateSubmissionMutation, useGetSubmissionQuery } from '@/store/api/gateway'
import { skipToken } from '@reduxjs/toolkit/query'
import { useEffect, type ReactElement } from 'react'
import { Avatar, Box, Button, Chip, IconButton, Link, Paper, Stack, ThemeProvider, Typography } from '@mui/material'
import { Close } from '@mui/icons-material'
Expand All @@ -14,8 +16,6 @@ import SafeThemeProvider from '@/components/theme/SafeThemeProvider'
import useChainId from '@/hooks/useChainId'
import useSafeAddress from '@/hooks/useSafeAddress'
import useWallet from '@/hooks/wallets/useWallet'
import { createSubmission } from '@safe-global/safe-client-gateway-sdk'
import useSubmission from '@/features/targetedOutreach/hooks/useSubmission'

const OutreachPopup = (): ReactElement | null => {
const dispatch = useAppDispatch()
Expand All @@ -24,7 +24,17 @@ const OutreachPopup = (): ReactElement | null => {
const currentChainId = useChainId()
const safeAddress = useSafeAddress()
const wallet = useWallet()
const submission = useSubmission()
const [createSubmission] = useCreateSubmissionMutation()
const { data: submission } = useGetSubmissionQuery(
!wallet || !safeAddress
? skipToken
: {
outreachId: ACTIVE_OUTREACH.id,
chainId: currentChainId,
safeAddress,
signerAddress: wallet?.address,
},
)

const [askAgainLaterTimestamp, setAskAgainLaterTimestamp] = useSessionStorage<number>(OUTREACH_SS_KEY)

Expand Down Expand Up @@ -54,10 +64,10 @@ const OutreachPopup = (): ReactElement | null => {
const handleOpenSurvey = async () => {
if (wallet) {
await createSubmission({
params: {
path: { outreachId: ACTIVE_OUTREACH.id, chainId: currentChainId, safeAddress, signerAddress: wallet.address },
},
body: { completed: true },
outreachId: ACTIVE_OUTREACH.id,
chainId: currentChainId,
safeAddress,
signerAddress: wallet.address,
})
}
dispatch(closeOutreachBanner())
Expand All @@ -72,9 +82,9 @@ const OutreachPopup = (): ReactElement | null => {
<Paper className={css.container}>
<Stack gap={2}>
<Box display="flex">
<Avatar alt="Clem Bihorel" src="/images/common/outreach-popup-avatar.png" />
<Avatar alt="Clem, product lead" src="/images/common/outreach-popup-avatar.png" />
<Box ml={1}>
<Typography variant="body2">Clem Bihorel</Typography>
<Typography variant="body2">Clem</Typography>
<Typography variant="body2" color="primary.light">
Product Lead
</Typography>
Expand Down
2 changes: 1 addition & 1 deletion src/features/targetedOutreach/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const ACTIVE_OUTREACH = { id: 1, url: 'https://wn2n6ocviur.typeform.com/to/J1OK3Ikf' }
export const ACTIVE_OUTREACH = { id: 1, url: 'https://app.opinionx.co/safe-power-user-survey/' }

export const OUTREACH_LS_KEY = 'outreachPopup'
export const OUTREACH_SS_KEY = 'outreachPopup_session'
Expand Down
27 changes: 0 additions & 27 deletions src/features/targetedOutreach/hooks/useSubmission.tsx

This file was deleted.

21 changes: 20 additions & 1 deletion src/store/api/gateway/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createApi, fakeBaseQuery } from '@reduxjs/toolkit/query/react'
import { getTransactionDetails, type TransactionDetails } from '@safe-global/safe-gateway-typescript-sdk'
import { asError } from '@/services/exceptions/utils'
import { safeOverviewEndpoints } from './safeOverviews'
import { getSubmission } from '@safe-global/safe-client-gateway-sdk'
import { createSubmission, getSubmission } from '@safe-global/safe-client-gateway-sdk'

export async function buildQueryFn<T>(fn: () => Promise<T>) {
try {
Expand All @@ -17,6 +17,7 @@ export async function buildQueryFn<T>(fn: () => Promise<T>) {
export const gatewayApi = createApi({
reducerPath: 'gatewayApi',
baseQuery: fakeBaseQuery<Error>(),
tagTypes: ['Submissions'],
endpoints: (builder) => ({
getTransactionDetails: builder.query<TransactionDetails, { chainId: string; txId: string }>({
queryFn({ chainId, txId }) {
Expand All @@ -37,6 +38,23 @@ export const gatewayApi = createApi({
getSubmission({ params: { path: { outreachId, chainId, safeAddress, signerAddress } } }),
)
},
providesTags: ['Submissions'],
}),
createSubmission: builder.mutation<
createSubmission,
{ outreachId: number; chainId: string; safeAddress: string; signerAddress: string }
>({
queryFn({ outreachId, chainId, safeAddress, signerAddress }) {
return buildQueryFn(() =>
createSubmission({
params: {
path: { outreachId, chainId, safeAddress, signerAddress },
},
body: { completed: true },
}),
)
},
invalidatesTags: ['Submissions'],
}),
...proposerEndpoints(builder),
...safeOverviewEndpoints(builder),
Expand All @@ -51,6 +69,7 @@ export const {
useDeleteProposerMutation,
useAddProposerMutation,
useGetSubmissionQuery,
useCreateSubmissionMutation,
useGetSafeOverviewQuery,
useGetMultipleSafeOverviewsQuery,
} = gatewayApi
2 changes: 1 addition & 1 deletion src/store/api/gateway/proposers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getDelegates } from '@safe-global/safe-gateway-typescript-sdk'
import type { Delegate, DelegateResponse } from '@safe-global/safe-gateway-typescript-sdk/dist/types/delegates'

export const proposerEndpoints = (
builder: EndpointBuilder<ReturnType<typeof fakeBaseQuery<Error>>, never, 'gatewayApi'>,
builder: EndpointBuilder<ReturnType<typeof fakeBaseQuery<Error>>, 'Submissions', 'gatewayApi'>,
) => ({
getProposers: builder.query<DelegateResponse, { chainId: string; safeAddress: string }>({
queryFn({ chainId, safeAddress }) {
Expand Down
2 changes: 1 addition & 1 deletion src/store/api/gateway/safeOverviews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ type MultiOverviewQueryParams = {
safes: SafeItem[]
}

export const safeOverviewEndpoints = (builder: EndpointBuilder<any, never, 'gatewayApi'>) => ({
export const safeOverviewEndpoints = (builder: EndpointBuilder<any, 'Submissions', 'gatewayApi'>) => ({
getSafeOverview: builder.query<SafeOverview | null, { safeAddress: string; walletAddress?: string; chainId: string }>(
{
async queryFn({ safeAddress, walletAddress, chainId }, { getState }) {
Expand Down
31 changes: 28 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17238,7 +17238,16 @@ string-length@^4.0.1:
char-regex "^1.0.2"
strip-ansi "^6.0.0"

"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
"string-width-cjs@npm:string-width@^4.2.0":
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"

string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
Expand Down Expand Up @@ -17334,7 +17343,14 @@ stringify-object@^3.3.0:
is-obj "^1.0.1"
is-regexp "^1.0.0"

"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"

strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
Expand Down Expand Up @@ -19090,7 +19106,7 @@ workbox-window@7.0.0:
"@types/trusted-types" "^2.0.2"
workbox-core "7.0.0"

"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
Expand All @@ -19108,6 +19124,15 @@ wrap-ansi@^6.2.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
Expand Down

0 comments on commit b5b354d

Please sign in to comment.