// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. import React, {useCallback, useMemo} from 'react'; import {View} from 'react-native'; import {removePost} from '@actions/local/post'; import CompassIcon from '@components/compass_icon'; import FormattedText from '@components/formatted_text'; import FormattedTime from '@components/formatted_time'; import ExpiryTimer from '@components/post_list/post/header/expiry_timer'; import PostPriorityLabel from '@components/post_priority/post_priority_label'; import {CHANNEL, THREAD} from '@constants/screens'; import {useServerUrl} from '@context/server'; import {useTheme} from '@context/theme'; import {DEFAULT_LOCALE} from '@i18n'; import {isOwnBoRPost, isUnrevealedBoRPost} from '@utils/bor'; import {postUserDisplayName} from '@utils/post'; import {makeStyleSheetFromTheme} from '@utils/theme'; import {ensureString} from '@utils/types'; import {typography} from '@utils/typography'; import {displayUsername, getUserCustomStatus, getUserTimezone, isCustomStatusExpired} from '@utils/user'; import HeaderCommentedOn from './commented_on'; import HeaderDisplayName from './display_name'; import HeaderReply from './reply'; import HeaderTag from './tag'; import type PostModel from '@typings/database/models/servers/post'; import type UserModel from '@typings/database/models/servers/user'; import type {AvailableScreens} from '@typings/screens/navigation'; type HeaderProps = { author?: UserModel; commentCount: number; currentUser?: UserModel; enablePostUsernameOverride: boolean; isAutoResponse: boolean; isCRTEnabled?: boolean; isCustomStatusEnabled: boolean; isEphemeral: boolean; isMilitaryTime: boolean; isPendingOrFailed: boolean; isSystemPost: boolean; isWebHook: boolean; location: AvailableScreens; post: PostModel; rootPostAuthor?: UserModel; showPostPriority: boolean; shouldRenderReplyButton?: boolean; teammateNameDisplay: string; hideGuestTags: boolean; } const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => { return { container: { flex: 1, marginTop: 10, }, pendingPost: { opacity: 0.5, }, wrapper: { flex: 1, flexDirection: 'row', alignItems: 'center', gap: 5, }, time: { color: theme.centerChannelColor, opacity: 0.5, ...typography('Body', 75, 'Regular'), }, visibleToYou: { color: theme.centerChannelColor, opacity: 0.5, ...typography('Body', 75, 'Regular'), }, }; }); const Header = (props: HeaderProps) => { const { author, commentCount = 0, currentUser, enablePostUsernameOverride, isAutoResponse, isCRTEnabled, isCustomStatusEnabled, isEphemeral, isMilitaryTime, isPendingOrFailed, isSystemPost, isWebHook, location, post, rootPostAuthor, showPostPriority, shouldRenderReplyButton, teammateNameDisplay, hideGuestTags, } = props; const theme = useTheme(); const style = getStyleSheet(theme); const pendingPostStyle = isPendingOrFailed ? style.pendingPost : undefined; const isReplyPost = Boolean(post.rootId && !isEphemeral); const showReply = !isReplyPost && (location !== THREAD) && (shouldRenderReplyButton && (!rootPostAuthor && commentCount > 0)); const displayName = postUserDisplayName(post, author, teammateNameDisplay, enablePostUsernameOverride); const rootAuthorDisplayName = rootPostAuthor ? displayUsername(rootPostAuthor, currentUser?.locale, teammateNameDisplay, true) : undefined; const customStatus = getUserCustomStatus(author); const showCustomStatusEmoji = Boolean( isCustomStatusEnabled && displayName && customStatus && !(isSystemPost || author?.isBot || isAutoResponse || isWebHook), ) && !isCustomStatusExpired(author) && Boolean(customStatus?.emoji); const userIconOverride = ensureString(post.props?.override_icon_url); const usernameOverride = ensureString(post.props?.override_username); const isUnrevealedPost = useMemo(() => isUnrevealedBoRPost(post), [post, post.metadata?.expire_at]); const ownBoRPost = useMemo(() => isOwnBoRPost(post, currentUser), [currentUser, post]); const showBoRIcon = isUnrevealedPost || ownBoRPost; const borExpireAt = post.metadata?.expire_at; const serverUrl = useServerUrl(); const onBoRPostExpiry = useCallback(async () => { await removePost(serverUrl, post); }, [post, serverUrl]); return ( <> {(!isSystemPost || isAutoResponse) && } {isEphemeral && ( )} {showPostPriority && post.metadata?.priority?.priority && ( )} {showBoRIcon && } { !showBoRIcon && Boolean(borExpireAt) && } {!isCRTEnabled && showReply && commentCount > 0 && } {Boolean(rootAuthorDisplayName) && location === CHANNEL && } ); }; export default Header;