Skip to content

Commit

Permalink
feat: add new notification styles in feed
Browse files Browse the repository at this point in the history
  • Loading branch information
andyesp committed Oct 6, 2023
1 parent 8c076bf commit d452436
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 54 deletions.
6 changes: 5 additions & 1 deletion src/components/Notifications/NotificationItem.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
display: flex;
flex-direction: row;
gap: 12px;
padding: 0 16px;
padding: 8px 16px;
}

.NotificationItem--new {
background-color: var(--alpha-blue-200);
}

.NotificationItem__IconContainer {
Expand Down
10 changes: 8 additions & 2 deletions src/components/Notifications/NotificationItem.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import classNames from 'classnames'

import { Notification, NotificationCustomType } from '../../shared/types/notifications'
import Time from '../../utils/date/Time'
import Link from '../Common/Typography/Link'
Expand All @@ -11,6 +13,7 @@ import './NotificationItem.css'

interface Props {
notification: Notification
isNew: boolean
}

function getIcon(metadata: { customType: string }) {
Expand All @@ -25,14 +28,17 @@ function getIcon(metadata: { customType: string }) {
}
}

export default function NotificationItem({ notification }: Props) {
export default function NotificationItem({ notification, isNew }: Props) {
const hasLink = !!notification.payload.data.acta
const Component = hasLink ? Link : 'div'
const metadata = notification.payload.data.additionalMeta?.data || ''
const Icon = getIcon(metadata ? JSON.parse(metadata) : null)

return (
<Component className="NotificationItem" href={notification.payload.data.acta}>
<Component
className={classNames('NotificationItem', isNew && 'NotificationItem--new')}
href={notification.payload.data.acta}
>
<div className="NotificationItem__IconContainer">
<Icon />
</div>
Expand Down
64 changes: 62 additions & 2 deletions src/components/Notifications/Notifications.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { useState } from 'react'
import { useMemo, useState } from 'react'

import { ChainId } from '@dcl/schemas/dist/dapps/chain-id'
import * as PushAPI from '@pushprotocol/restapi'
import { useQuery } from '@tanstack/react-query'
import classNames from 'classnames'
import useAuthContext from 'decentraland-gatsby/dist/context/Auth/useAuthContext'

import { Governance } from '../../clients/Governance'
import { PUSH_CHANNEL_ID } from '../../constants'
import { isSameAddress } from '../../entities/Snapshot/utils'
import { DEFAULT_QUERY_STALE_TIME } from '../../hooks/constants'
import useFormatMessage from '../../hooks/useFormatMessage'
import { getCaipAddress, getPushNotificationsEnv } from '../../utils/notifications'
import NotificationBellActive from '../Icon/NotificationBellActive'
import NotificationBellInactive from '../Icon/NotificationBellInactive'

Expand All @@ -11,8 +20,48 @@ import NotificationsFeed from './NotificationsFeed'

export default function Notifications() {
const t = useFormatMessage()
const [user, userState] = useAuthContext()
const [isOpen, setOpen] = useState(false)
const chainId = userState.chainId || ChainId.ETHEREUM_GOERLI
const hasNewNotifications = false // TODO: Integrate this
const lastNotificationId = 8403736 // TODO: Integrate this
const env = getPushNotificationsEnv(chainId)

const {
data: subscriptions,
refetch: refetchSubscriptions,
isLoading: isLoadingSubscriptions,
isRefetching: isRefetchingSubscriptions,
} = useQuery({
queryKey: [`pushSubscriptions#${user}`],
queryFn: () =>
user
? PushAPI.user.getSubscriptions({
user: getCaipAddress(user, chainId),
env,
})
: null,
enabled: !!user,
staleTime: DEFAULT_QUERY_STALE_TIME,
})

const isSubscribed = useMemo(
() => !!subscriptions?.find((item: { channel: string }) => isSameAddress(item.channel, PUSH_CHANNEL_ID)),
[subscriptions]
)

const {
data: userNotifications,
isLoading: isLoadingNotifications,
isRefetching: isRefetchingNotifications,
} = useQuery({
queryKey: [`notifications#${user}`],
queryFn: () => (user ? Governance.get().getUserNotifications(user) : null),
enabled: !!user && isSubscribed,
})

console.log('u', userNotifications)
console.log('s', subscriptions, PUSH_CHANNEL_ID)

return (
<>
Expand All @@ -30,7 +79,18 @@ export default function Notifications() {
)}
</button>
</div>
<NotificationsFeed isOpen={isOpen} onClose={() => setOpen(false)} />
<NotificationsFeed
isOpen={isOpen}
onClose={() => setOpen(false)}
userNotifications={userNotifications}
onSubscriptionChangeSuccess={refetchSubscriptions}
lastNotificationId={lastNotificationId}
isSubscribed={isSubscribed}
isLoadingNotifications={isLoadingNotifications}
isRefetchingNotifications={isRefetchingNotifications}
isLoadingSubscriptions={isLoadingSubscriptions}
isRefetchingSubscriptions={isRefetchingSubscriptions}
/>
</>
)
}
2 changes: 0 additions & 2 deletions src/components/Notifications/NotificationsFeed.css
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@
.NotificationsFeed__List {
display: flex;
flex-direction: column;
gap: 16px;
padding-bottom: 16px;
}

.NotificationsFeed__Content {
Expand Down
76 changes: 30 additions & 46 deletions src/components/Notifications/NotificationsFeed.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import { useEffect, useMemo, useState } from 'react'
import { useEffect, useState } from 'react'

import { ChainId } from '@dcl/schemas/dist/dapps/chain-id'
import { Web3Provider } from '@ethersproject/providers'
import * as PushAPI from '@pushprotocol/restapi'
import { useQuery } from '@tanstack/react-query'
import classNames from 'classnames'
import useAuthContext from 'decentraland-gatsby/dist/context/Auth/useAuthContext'
import { Button } from 'decentraland-ui/dist/components/Button/Button'
import { Loader } from 'decentraland-ui/dist/components/Loader/Loader'

import { Governance } from '../../clients/Governance'
import { PUSH_CHANNEL_ID } from '../../constants'
import { isSameAddress } from '../../entities/Snapshot/utils'
import { DEFAULT_QUERY_STALE_TIME } from '../../hooks/constants'
import { useClickOutside } from '../../hooks/useClickOutside'
import useFormatMessage from '../../hooks/useFormatMessage'
import { Notification } from '../../shared/types/notifications'
Expand All @@ -32,52 +28,38 @@ const NOTIFICATIONS_PER_PAGE = 5
interface Props {
isOpen: boolean
onClose: () => void
onSubscriptionChangeSuccess: () => void
userNotifications: Notification[] | null | undefined
isSubscribed: boolean
isLoadingNotifications: boolean
isRefetchingNotifications: boolean
isLoadingSubscriptions: boolean
isRefetchingSubscriptions: boolean
lastNotificationId: number
}

export default function NotificationsFeed({ isOpen, onClose }: Props) {
export default function NotificationsFeed({
isOpen,
onClose,
onSubscriptionChangeSuccess,
userNotifications,
isSubscribed,
isLoadingNotifications,
isRefetchingNotifications,
isLoadingSubscriptions,
isRefetchingSubscriptions,
lastNotificationId,
}: Props) {
const t = useFormatMessage()
const [isSubscribing, setIsSubscribing] = useState(false)
const [user, userState] = useAuthContext()
const [filteredNotifications, setFilteredNotifications] = useState<Notification[]>([])
const lastNotificationIdIndex = userNotifications?.findIndex((item) => item.payload_id === lastNotificationId)

useClickOutside('.NotificationsFeed', isOpen, onClose)
const chainId = userState.chainId || ChainId.ETHEREUM_GOERLI
const env = getPushNotificationsEnv(chainId)

const {
data: subscriptions,
refetch: refetchSubscriptions,
isLoading: isLoadingSubscriptions,
isRefetching: isRefetchingSubscriptions,
} = useQuery({
queryKey: [`pushSubscriptions#${user}`],
queryFn: () =>
user
? PushAPI.user.getSubscriptions({
user: getCaipAddress(user, chainId),
env,
})
: null,
enabled: !!user,
staleTime: DEFAULT_QUERY_STALE_TIME,
})

const isSubscribed = useMemo(
() => !!subscriptions?.find((item: { channel: string }) => isSameAddress(item.channel, PUSH_CHANNEL_ID)),
[subscriptions]
)

const {
data: userNotifications,
isLoading: isLoadingNotifications,
isRefetching: isRefetchingNotifications,
} = useQuery({
queryKey: [`notifications#${user}`],
queryFn: () => (user ? Governance.get().getUserNotifications(user) : null),
enabled: !!user && isSubscribed,
staleTime: DEFAULT_QUERY_STALE_TIME,
})

const handleSubscribeUserToChannel = async () => {
if (!user || !userState.provider) {
return
Expand All @@ -90,9 +72,7 @@ export default function NotificationsFeed({ isOpen, onClose }: Props) {
signer,
channelAddress: getCaipAddress(PUSH_CHANNEL_ID, chainId),
userAddress: getCaipAddress(user, chainId),
onSuccess: () => {
refetchSubscriptions()
},
onSuccess: onSubscriptionChangeSuccess,
env,
})

Expand All @@ -110,7 +90,7 @@ export default function NotificationsFeed({ isOpen, onClose }: Props) {
signer,
channelAddress: getCaipAddress(PUSH_CHANNEL_ID, chainId),
userAddress: getCaipAddress(user, chainId),
onSuccess: () => refetchSubscriptions(),
onSuccess: onSubscriptionChangeSuccess,
env,
})
}
Expand Down Expand Up @@ -178,8 +158,12 @@ export default function NotificationsFeed({ isOpen, onClose }: Props) {
{showNotifications && (
<div className="NotificationsFeed__ListContainer">
<div className="NotificationsFeed__List">
{filteredNotifications?.map((notification) => (
<NotificationItem key={notification.payload_id} notification={notification} />
{filteredNotifications?.map((notification, index) => (
<NotificationItem
key={notification.payload_id}
notification={notification}
isNew={!!lastNotificationIdIndex && index < lastNotificationIdIndex}
/>
))}
</div>
{showLoadMoreButton && (
Expand Down
2 changes: 1 addition & 1 deletion src/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
--alpha-black-200: rgba(115, 110, 125, 0.1);
--alpha-black-300: rgba(115, 110, 125, 0.24);
--alpha-black-400: rgba(115, 110, 125, 0.32);
--alpha-blue-200: rgba(72, 136, 238, 0.16);
--alpha-blue-200: rgba(226, 236, 252, 0.34);
--alpha-fuchsia-200: rgba(255, 90, 254, 0.16);
--alpha-fuchsia-500: rgba(255, 90, 254, 0.5);
--alpha-green-200: rgba(68, 182, 0, 0.16);
Expand Down

0 comments on commit d452436

Please sign in to comment.