import { useCallback, useState } from 'react'; import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import classNames from 'classnames'; import AddIcon from '@/material-icons/400-24px/add.svg?react'; import ArrowBackIcon from '@/material-icons/400-24px/arrow_back.svg?react'; import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react'; import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; import CloseIcon from '@/material-icons/400-24px/close.svg?react'; import SettingsIcon from '@/material-icons/400-24px/settings.svg?react'; import type { IconProp } from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon'; import { ButtonInTabsBar } from 'mastodon/features/ui/util/columns_context'; import { useIdentity } from 'mastodon/identity_context'; import { useAppHistory } from './router'; const messages = defineMessages({ show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' }, hide: { id: 'column_header.hide_settings', defaultMessage: 'Hide settings' }, moveLeft: { id: 'column_header.moveLeft_settings', defaultMessage: 'Move column to the left', }, moveRight: { id: 'column_header.moveRight_settings', defaultMessage: 'Move column to the right', }, back: { id: 'column_back_button.label', defaultMessage: 'Back' }, }); const BackButton: React.FC<{ onlyIcon: boolean; }> = ({ onlyIcon }) => { const history = useAppHistory(); const intl = useIntl(); const handleBackClick = useCallback(() => { if (history.location.state?.fromMastodon) { history.goBack(); } else { history.push('/'); } }, [history]); return ( ); }; export interface Props { title?: string; icon?: string; iconComponent?: IconProp; active?: boolean; children?: React.ReactNode; pinned?: boolean; multiColumn?: boolean; extraButton?: React.ReactNode; showBackButton?: boolean; placeholder?: boolean; appendContent?: React.ReactNode; collapseIssues?: boolean; onClick?: () => void; onMove?: (arg0: number) => void; onPin?: () => void; } export const ColumnHeader: React.FC = ({ title, icon, iconComponent, active, children, pinned, multiColumn, extraButton, showBackButton, placeholder, appendContent, collapseIssues, onClick, onMove, onPin, }) => { const intl = useIntl(); const { signedIn } = useIdentity(); const history = useAppHistory(); const [collapsed, setCollapsed] = useState(true); const [animating, setAnimating] = useState(false); const handleToggleClick = useCallback( (e: React.MouseEvent) => { e.stopPropagation(); setCollapsed((value) => !value); setAnimating(true); }, [setCollapsed, setAnimating], ); const handleTitleClick = useCallback(() => { onClick?.(); }, [onClick]); const handleMoveLeft = useCallback(() => { onMove?.(-1); }, [onMove]); const handleMoveRight = useCallback(() => { onMove?.(1); }, [onMove]); const handleTransitionEnd = useCallback(() => { setAnimating(false); }, [setAnimating]); const handlePin = useCallback(() => { if (!pinned) { history.replace('/'); } onPin?.(); }, [history, pinned, onPin]); const wrapperClassName = classNames('column-header__wrapper', { active, }); const buttonClassName = classNames('column-header', { active, }); const collapsibleClassName = classNames('column-header__collapsible', { collapsed, animating, }); const collapsibleButtonClassName = classNames('column-header__button', { active: !collapsed, }); let extraContent, pinButton, moveButtons, backButton, collapseButton; if (children) { extraContent = (
{children}
); } if (multiColumn && pinned) { pinButton = ( ); moveButtons = (
); } else if (multiColumn && onPin) { pinButton = ( ); } if ( !pinned && ((multiColumn && history.location.state?.fromMastodon) || showBackButton) ) { backButton = ; } const collapsedContent = [extraContent]; if (multiColumn) { collapsedContent.push(
{pinButton} {moveButtons}
, ); } if (signedIn && (children || (multiColumn && onPin))) { collapseButton = ( ); } const hasIcon = icon && iconComponent; const hasTitle = hasIcon && title; const component = (

{hasTitle && ( <> {backButton} )} {!hasTitle && backButton}
{extraButton} {collapseButton}

{(!collapsed || animating) && collapsedContent}
{appendContent}
); if (placeholder) { return component; } else { return {component}; } }; // eslint-disable-next-line import/no-default-export export default ColumnHeader;