69 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
/* 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 CloseIcon from '@/material-icons/400-24px/close.svg?react';
 | 
						|
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'
 | 
						|
          iconComponent={CloseIcon}
 | 
						|
          title={intl.formatMessage(messages.dismiss)}
 | 
						|
          onClick={handleDismiss}
 | 
						|
        />
 | 
						|
      </div>
 | 
						|
 | 
						|
      <div className='dismissable-banner__message'>{children}</div>
 | 
						|
    </div>
 | 
						|
  );
 | 
						|
};
 |