import menuInstance from '@components/contextMenu/instance' import menuShare from '@components/contextMenu/share' import menuStatus from '@components/contextMenu/status' import TimelineActioned from '@components/Timeline/Shared/Actioned' import TimelineActions from '@components/Timeline/Shared/Actions' import TimelineAttachment from '@components/Timeline/Shared/Attachment' import TimelineAvatar from '@components/Timeline/Shared/Avatar' import TimelineCard from '@components/Timeline/Shared/Card' import TimelineContent from '@components/Timeline/Shared/Content' import TimelineHeaderDefault from '@components/Timeline/Shared/HeaderDefault' import TimelinePoll from '@components/Timeline/Shared/Poll' import { useNavigation } from '@react-navigation/native' import { StackNavigationProp } from '@react-navigation/stack' import { featureCheck } from '@utils/helpers/featureCheck' import { checkIsMyAccount } from '@utils/helpers/isMyAccount' import removeHTML from '@utils/helpers/removeHTML' import { TabLocalStackParamList } from '@utils/navigation/navigators' import { usePreferencesQuery } from '@utils/queryHooks/preferences' import { QueryKeyTimeline } from '@utils/queryHooks/timeline' import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' import React, { Fragment, useRef, useState } from 'react' import { Pressable, StyleProp, View, ViewStyle } from 'react-native' import * as ContextMenu from 'zeego/context-menu' import StatusContext from './Shared/Context' import TimelineFeedback from './Shared/Feedback' import TimelineFiltered, { FilteredProps, shouldFilter } from './Shared/Filtered' import TimelineFullConversation from './Shared/FullConversation' import TimelineHeaderAndroid from './Shared/HeaderAndroid' import TimelineTranslate from './Shared/Translate' export interface Props { item: Mastodon.Status & { _pinned?: boolean } // For account page, internal property queryKey?: QueryKeyTimeline highlighted?: boolean suppressSpoiler?: boolean // Same content as the main thread, can be dimmed disableDetails?: boolean disableOnPress?: boolean isConversation?: boolean noBackground?: boolean } // When the poll is long const TimelineDefault: React.FC = ({ item, queryKey, highlighted = false, suppressSpoiler = false, disableDetails = false, disableOnPress = false, isConversation = false, noBackground = false }) => { const status = item.reblog ? item.reblog : item const rawContent = useRef([]) if (highlighted || isConversation) { rawContent.current = [ removeHTML(status.content), status.spoiler_text ? removeHTML(status.spoiler_text) : '' ].filter(c => c.length) } const { colors } = useTheme() const navigation = useNavigation>() const { data: preferences } = usePreferencesQuery() const isMyAccount = checkIsMyAccount(status.account.id) const [spoilerExpanded, setSpoilerExpanded] = useState( preferences?.['reading:expand:spoilers'] || false ) const spoilerHidden = status.spoiler_text?.length ? !preferences?.['reading:expand:spoilers'] && !spoilerExpanded : false const detectedLanguage = useRef(status.language || '') const excludeMentions = useRef([]) const mainStyle: StyleProp = { flex: 1, padding: disableDetails ? StyleConstants.Spacing.Global.PagePadding / 1.5 : StyleConstants.Spacing.Global.PagePadding, backgroundColor: noBackground ? undefined : colors.backgroundDefault, paddingBottom: disableDetails ? StyleConstants.Spacing.Global.PagePadding / 1.5 : 0 } const main = () => ( <> {item.reblog ? ( ) : item._pinned ? ( ) : null} ) const mShare = menuShare({ visibility: status.visibility, type: 'status', url: status.url || status.uri, rawContent }) const mStatus = menuStatus({ status, queryKey }) const mInstance = menuInstance({ status, queryKey }) if (!isMyAccount) { let filterResults: FilteredProps['filterResults'] = [] const [filterRevealed, setFilterRevealed] = useState(false) const hasFilterServerSide = featureCheck('filter_server_side') if (hasFilterServerSide) { if (status.filtered?.length) { filterResults = status.filtered?.map(filter => filter.filter) } } else { if (queryKey) { const checkFilter = shouldFilter({ queryKey, status }) if (checkFilter?.length) { filterResults = checkFilter } } } if (queryKey && !highlighted && filterResults?.length && !filterRevealed) { return !filterResults.filter(result => result.filter_action === 'hide').length ? ( setFilterRevealed(!filterRevealed)}> ) : null } } return ( {disableOnPress ? ( {main()} ) : ( <> navigation.push('Tab-Shared-Toot', { toot: status })} onLongPress={() => {}} children={main()} /> {[mShare, mStatus, mInstance].map((menu, i) => ( {menu.map((group, index) => ( {group.map(item => { switch (item.type) { case 'item': return ( {item.icon ? ( ) : null} ) case 'sub': return ( // @ts-ignore {item.trigger.icon ? ( ) : null} {item.items.map(sub => ( {sub.icon ? ( ) : null} ))} ) } })} ))} ))} )} ) } export default React.memo(TimelineDefault)