// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {useIntl} from 'react-intl';
import {
Text,
TouchableOpacity,
View,
} from 'react-native';
import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
import {dismissAnnouncement} from '@actions/local/systems';
import CompassIcon from '@components/compass_icon';
import RemoveMarkdown from '@components/remove_markdown';
import {ANNOUNCEMENT_BAR_HEIGHT} from '@constants/view';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {bottomSheet} from '@screens/navigation';
import {bottomSheetSnapPoint} from '@utils/helpers';
import {getMarkdownTextStyles} from '@utils/markdown';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
import ExpandedAnnouncementBanner from './expanded_announcement_banner';
type Props = {
bannerColor: string;
bannerDismissed: boolean;
bannerEnabled: boolean;
bannerText?: string;
bannerTextColor?: string;
allowDismissal: boolean;
}
const getStyle = makeStyleSheetFromTheme((theme: Theme) => ({
background: {
backgroundColor: theme.sidebarBg,
zIndex: 1,
},
bannerContainer: {
flex: 1,
paddingHorizontal: 10,
overflow: 'hidden',
flexDirection: 'row',
alignItems: 'center',
marginHorizontal: 8,
borderRadius: 7,
},
wrapper: {
flexDirection: 'row',
flex: 1,
overflow: 'hidden',
},
bannerTextContainer: {
flex: 1,
flexGrow: 1,
marginRight: 5,
textAlign: 'center',
},
bannerText: {
...typography('Body', 100, 'SemiBold'),
},
}));
const CLOSE_BUTTON_ID = 'announcement-close';
const BUTTON_HEIGHT = 48; // From /app/utils/buttonStyles.ts, lg button
const TITLE_HEIGHT = 30 + 12; // typography 600 line height
const MARGINS = 12 + 24 + 10; // (after title + after text + after content) from ./expanded_announcement_banner.tsx
const TEXT_CONTAINER_HEIGHT = 150;
const DISMISS_BUTTON_HEIGHT = BUTTON_HEIGHT + 10; // Top margin from ./expanded_announcement_banner.tsx
const SNAP_POINT_WITHOUT_DISMISS = TITLE_HEIGHT + BUTTON_HEIGHT + MARGINS + TEXT_CONTAINER_HEIGHT;
const AnnouncementBanner = ({
bannerColor,
bannerDismissed,
bannerEnabled,
bannerText = '',
bannerTextColor = '#000',
allowDismissal,
}: Props) => {
const intl = useIntl();
const serverUrl = useServerUrl();
const height = useSharedValue(0);
const theme = useTheme();
const [visible, setVisible] = useState(false);
const style = getStyle(theme);
const markdownTextStyles = getMarkdownTextStyles(theme);
const renderContent = useCallback(() => (
), [allowDismissal, bannerText]);
const handlePress = useCallback(() => {
const title = intl.formatMessage({
id: 'mobile.announcement_banner.title',
defaultMessage: 'Announcement',
});
const snapPoint = bottomSheetSnapPoint(
1,
SNAP_POINT_WITHOUT_DISMISS + (allowDismissal ? DISMISS_BUTTON_HEIGHT : 0),
);
bottomSheet({
closeButtonId: CLOSE_BUTTON_ID,
title,
renderContent,
snapPoints: [1, snapPoint],
theme,
});
}, [intl, allowDismissal, renderContent, theme]);
const handleDismiss = useCallback(() => {
dismissAnnouncement(serverUrl, bannerText);
}, [serverUrl, bannerText]);
useEffect(() => {
const showBanner = bannerEnabled && !bannerDismissed && Boolean(bannerText);
setVisible(showBanner);
}, [bannerDismissed, bannerEnabled, bannerText]);
useEffect(() => {
height.value = withTiming(visible ? ANNOUNCEMENT_BAR_HEIGHT : 0, {
duration: 200,
});
}, [height, visible]);
const bannerStyle = useAnimatedStyle(() => ({
height: height.value,
}));
const bannerTextContainerStyle = useMemo(() => [style.bannerTextContainer, {
color: bannerTextColor,
}], [style, bannerTextColor]);
return (
{visible &&
<>
{' '}
{allowDismissal && (
)
}
>
}
);
};
export default AnnouncementBanner;