import React, { useCallback, useEffect, useMemo, useState } from 'react' import { ActivityIndicator, Pressable, StyleSheet, Text, View } from 'react-native' import { useNavigation } from '@react-navigation/native' import { Feather } from '@expo/vector-icons' import Emojis from '@components/Timelines/Timeline/Shared/Emojis' import relativeTime from '@utils/relativeTime' import { useTheme } from '@utils/styles/ThemeManager' import { StyleConstants } from '@utils/styles/constants' import { useQuery } from 'react-query' import { relationshipFetch } from '@utils/fetches/relationshipFetch' import client from '@api/client' import { toast } from '@components/toast' export interface Props { notification: Mastodon.Notification } const TimelineHeaderNotification: React.FC = ({ notification }) => { const name = notification.account.display_name || notification.account.username const emojis = notification.account.emojis const account = notification.account.acct const { theme } = useTheme() const navigation = useNavigation() const [since, setSince] = useState(relativeTime(notification.created_at)) const { status, data, refetch } = useQuery( ['Relationship', { id: notification.account.id }], relationshipFetch, { enabled: false } ) const [updateData, setUpdateData] = useState< Mastodon.Relationship | undefined >() useEffect(() => { setTimeout(() => { setSince(relativeTime(notification.created_at)) }, 1000) }, [since]) const applicationOnPress = useCallback(() => { navigation.navigate('Screen-Shared-Webview', { uri: notification.status?.application!.website }) }, []) const relationshipOnPress = useCallback(() => { client({ method: 'post', instance: 'local', url: `accounts/${notification.account.id}/${ updateData ? updateData.following || updateData.requested ? 'un' : '' : data!.following || data!.requested ? 'un' : '' }follow` }).then(res => { if (res.body.id === (updateData && updateData.id) || data!.id) { setUpdateData(res.body) return Promise.resolve() } else { toast({ type: 'error', content: '请重试', autoHide: false }) return Promise.reject() } }) }, [data, updateData]) useEffect(() => { if (notification.type === 'follow') { refetch() } }, [notification.type]) const relationshipIcon = useMemo(() => { switch (status) { case 'idle': case 'loading': return case 'success': return ( ) default: return null } }, [status, data, updateData]) return ( {emojis?.length ? ( ) : ( {name} )} @{account} {since} {notification.status?.visibility === 'private' && ( )} {notification.status?.application && notification.status?.application.name !== 'Web' && ( 发自于 - {notification.status?.application.name} )} {notification.type === 'follow' && ( {relationshipIcon} )} ) } const styles = StyleSheet.create({ base: { flex: 1, flexDirection: 'row' }, nameAndMeta: { width: '80%' }, name: { flexDirection: 'row' }, nameWithoutEmoji: { fontSize: StyleConstants.Font.Size.M, fontWeight: StyleConstants.Font.Weight.Bold }, account: { flexShrink: 1, marginLeft: StyleConstants.Spacing.XS }, meta: { flexDirection: 'row', alignItems: 'center', marginTop: StyleConstants.Spacing.XS, marginBottom: StyleConstants.Spacing.S }, created_at: { fontSize: StyleConstants.Font.Size.S }, visibility: { marginLeft: StyleConstants.Spacing.S }, application: { fontSize: StyleConstants.Font.Size.S, marginLeft: StyleConstants.Spacing.S }, relationship: { flexBasis: '20%', flexDirection: 'row', justifyContent: 'center' } }) export default React.memo(TimelineHeaderNotification, () => true)