You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
1.9 KiB
66 lines
1.9 KiB
/* eslint-disable @typescript-eslint/no-unsafe-call, |
|
@typescript-eslint/no-unsafe-return, |
|
@typescript-eslint/no-unsafe-assignment, |
|
@typescript-eslint/no-unsafe-member-access |
|
-- the settings store is not yet typed */ |
|
import type { PropsWithChildren } from 'react'; |
|
import { useCallback, useState, useEffect } from 'react'; |
|
|
|
import { defineMessages, useIntl } from 'react-intl'; |
|
|
|
import { changeSetting } from 'mastodon/actions/settings'; |
|
import { bannerSettings } from 'mastodon/settings'; |
|
import { useAppSelector, useAppDispatch } from 'mastodon/store'; |
|
|
|
import { IconButton } from './icon_button'; |
|
|
|
const messages = defineMessages({ |
|
dismiss: { id: 'dismissable_banner.dismiss', defaultMessage: 'Dismiss' }, |
|
}); |
|
|
|
interface Props { |
|
id: string; |
|
} |
|
|
|
export const DismissableBanner: React.FC<PropsWithChildren<Props>> = ({ |
|
id, |
|
children, |
|
}) => { |
|
const dismissed = useAppSelector((state) => |
|
state.settings.getIn(['dismissed_banners', id], false), |
|
); |
|
const dispatch = useAppDispatch(); |
|
|
|
const [visible, setVisible] = useState(!bannerSettings.get(id) && !dismissed); |
|
const intl = useIntl(); |
|
|
|
const handleDismiss = useCallback(() => { |
|
setVisible(false); |
|
bannerSettings.set(id, true); |
|
dispatch(changeSetting(['dismissed_banners', id], true)); |
|
}, [id, dispatch]); |
|
|
|
useEffect(() => { |
|
if (!visible && !dismissed) { |
|
dispatch(changeSetting(['dismissed_banners', id], true)); |
|
} |
|
}, [id, dispatch, visible, dismissed]); |
|
|
|
if (!visible) { |
|
return null; |
|
} |
|
|
|
return ( |
|
<div className='dismissable-banner'> |
|
<div className='dismissable-banner__action'> |
|
<IconButton |
|
icon='times' |
|
title={intl.formatMessage(messages.dismiss)} |
|
onClick={handleDismiss} |
|
/> |
|
</div> |
|
|
|
<div className='dismissable-banner__message'>{children}</div> |
|
</div> |
|
); |
|
};
|
|
|