Skip to content
This repository has been archived by the owner on Jun 24, 2022. It is now read-only.

[Affiliate] Update banner closed state across tabs #1875

Merged
merged 4 commits into from
Nov 24, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
18 changes: 13 additions & 5 deletions src/custom/components/NotificationBanner/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from 'react'
import { useEffect, useState } from 'react'
import styled from 'styled-components/macro'
import { Colors } from 'theme/styled'
import { X } from 'react-feather'
Expand Down Expand Up @@ -50,10 +50,12 @@ const BannerContainer = styled.div`
justify-content: center;
`
export default function NotificationBanner(props: BannerProps) {
const { id, canClose = true } = props
const { id, isVisible, canClose = true } = props
const dispatch = useAppDispatch()
const isNotificationClosed = useIsNotificationClosed(id) // TODO: the notification closed state is now tied to the Affiliate state, this should generic
const [isActive, setIsActive] = useState(!isNotificationClosed ?? props.isVisible)
const isNotificationClosed = useIsNotificationClosed(id) // TODO: the notification closed state is now tied to the Affiliate state, this should be generic
const [isActive, setIsActive] = useState(!isNotificationClosed ?? isVisible)

const isHidden = !isVisible || isNotificationClosed || !isActive

const handleClose = () => {
setIsActive(false)
Expand All @@ -62,8 +64,14 @@ export default function NotificationBanner(props: BannerProps) {
}
}

useEffect(() => {
if (isNotificationClosed !== null) {
setIsActive(!isNotificationClosed)
}
}, [isNotificationClosed, isActive])

return (
<Banner {...props} isVisible={isActive}>
<Banner {...props} isVisible={!isHidden}>
<BannerContainer>{props.children}</BannerContainer>
{canClose && <StyledClose size={24} onClick={handleClose} />}
</Banner>
Expand Down
2 changes: 1 addition & 1 deletion src/custom/state/affiliate/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function useResetReferralAddress() {
return useCallback(() => dispatch(updateReferralAddress(null)), [dispatch])
}

export function useIsNotificationClosed(id?: string) {
export function useIsNotificationClosed(id?: string): boolean | null {
return useSelector<AppState, boolean | null>((state) => {
return id ? state.affiliate.isNotificationClosed?.[id] ?? false : null
})
Expand Down
40 changes: 37 additions & 3 deletions src/custom/state/affiliate/updater.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { useEffect } from 'react'
import { useCallback, useEffect } from 'react'

import { updateReferralAddress } from 'state/affiliate/actions'
import { dismissNotification, updateReferralAddress } from 'state/affiliate/actions'
import useParseReferralQueryParam from 'hooks/useParseReferralQueryParam'
import { useAppDispatch } from 'state/hooks'
import { useReferralAddress } from 'state/affiliate/hooks'
import { AffiliateState } from './reducer'

export default function ReferralLinkUpdater() {
export function ReferralLinkUpdater() {
const dispatch = useAppDispatch()
const referralAddressParam = useParseReferralQueryParam()
const referralAddress = useReferralAddress()
Expand All @@ -20,3 +21,36 @@ export default function ReferralLinkUpdater() {

return null
}

export function NotificationClosedUpdater() {
const dispatch = useAppDispatch()

const handler = useCallback(
(e: StorageEvent) => {
if (e.key === 'redux_localstorage_simple_affiliate' && e.newValue) {
alfetopito marked this conversation as resolved.
Show resolved Hide resolved
const parsed = JSON.parse(e.newValue) as AffiliateState
for (const id in parsed.isNotificationClosed) {
dispatch(dismissNotification(id))
}
}
},
[dispatch]
)

useEffect(() => {
window.addEventListener('storage', handler)

return () => window.removeEventListener('storage', handler)
}, [handler])

return null
}

export default function AffiliateUpdaters() {
return (
<>
<ReferralLinkUpdater />
<NotificationClosedUpdater />
</>
)
}