import React, { useEffect, useState } from 'react' import { ActionSheetIOS, Clipboard, Modal, Pressable, StyleSheet, Text, View } from 'react-native' import Toast from 'react-native-toast-message' import { useMutation, useQueryCache } from 'react-query' import { Feather } from '@expo/vector-icons' import client from 'src/api/client' import { getLocalAccountId } from 'src/utils/slices/instancesSlice' import { store } from 'src/store' import { useTheme } from 'src/utils/styles/ThemeManager' import constants from 'src/utils/styles/constants' const fireMutation = async ({ id, type, stateKey, prevState }: { id: string type: | 'favourite' | 'reblog' | 'bookmark' | 'mute' | 'pin' | 'delete' | 'account/mute' stateKey: | 'favourited' | 'reblogged' | 'bookmarked' | 'muted' | 'pinned' | 'id' prevState?: boolean }) => { let res switch (type) { case 'favourite': case 'reblog': case 'bookmark': case 'mute': case 'pin': res = await client({ method: 'post', instance: 'local', endpoint: `statuses/${id}/${prevState ? 'un' : ''}${type}` }) if (!res.body[stateKey] === prevState) { if (type === 'bookmark' || 'mute' || 'pin') Toast.show({ type: 'success', position: 'bottom', text1: '功能成功', visibilityTime: 2000, autoHide: true, bottomOffset: 65 }) return Promise.resolve(res.body) } else { Toast.show({ type: 'error', position: 'bottom', text1: '请重试', autoHide: false, bottomOffset: 65 }) return Promise.reject() } break case 'delete': res = await client({ method: 'delete', instance: 'local', endpoint: `statuses/${id}` }) if (res.body[stateKey] === id) { Toast.show({ type: 'success', position: 'bottom', text1: '删除成功', visibilityTime: 2000, autoHide: true, bottomOffset: 65 }) return Promise.resolve(res.body) } else { Toast.show({ type: 'error', position: 'bottom', text1: '请重试', autoHide: false, bottomOffset: 65 }) return Promise.reject() } break } } export interface Props { queryKey: App.QueryKey status: Mastodon.Status } const ActionsStatus: React.FC = ({ queryKey, status }) => { const { theme } = useTheme() const iconColor = theme.secondary const iconColorAction = (state: boolean) => state ? theme.primary : theme.secondary const localAccountId = getLocalAccountId(store.getState()) const [modalVisible, setModalVisible] = useState(false) const queryCache = useQueryCache() const [mutateAction] = useMutation(fireMutation, { onMutate: () => { queryCache.cancelQueries(queryKey) const prevData = queryCache.getQueryData(queryKey) return prevData }, onSuccess: (newData, params) => { if (params.type === 'reblog') { queryCache.invalidateQueries(['Following', { page: 'Following' }]) } // queryCache.setQueryData(queryKey, (oldData: any) => { // oldData && // oldData.map((paging: any) => { // paging.toots.map( // (status: Mastodon.Status | Mastodon.Notification, i: number) => { // if (status.id === newData.id) { // paging.toots[i] = newData // } // } // ) // }) // return oldData // }) return Promise.resolve() }, onError: (err, variables, prevData) => { queryCache.setQueryData(queryKey, prevData) }, onSettled: () => { queryCache.invalidateQueries(queryKey) } }) return ( <> {status.replies_count > 0 && ( {status.replies_count} )} mutateAction({ id: status.id, type: 'reblog', stateKey: 'reblogged', prevState: status.reblogged }) } > mutateAction({ id: status.id, type: 'favourite', stateKey: 'favourited', prevState: status.favourited }) } > mutateAction({ id: status.id, type: 'bookmark', stateKey: 'bookmarked', prevState: status.bookmarked }) } > setModalVisible(true)}> setModalVisible(false)} > ActionSheetIOS.showShareActionSheetWithOptions( { url: status.uri, excludedActivityTypes: [ 'com.apple.UIKit.activity.Mail', 'com.apple.UIKit.activity.Print', 'com.apple.UIKit.activity.SaveToCameraRoll', 'com.apple.UIKit.activity.OpenInIBooks' ] }, () => {}, () => { setModalVisible(false) Toast.show({ type: 'success', position: 'bottom', text1: '分享成功', visibilityTime: 2000, autoHide: true, bottomOffset: 65 }) } ) } > 分享 { Clipboard.setString(status.uri) setModalVisible(false) Toast.show({ type: 'success', position: 'bottom', text1: '链接复制成功', visibilityTime: 2000, autoHide: true, bottomOffset: 65 }) }} > 复制链接 {status.account.id === localAccountId && ( { setModalVisible(false) mutateAction({ id: status.id, type: 'delete', stateKey: 'id' }) }} > 删除 )} (删除并重发) { setModalVisible(false) mutateAction({ id: status.id, type: 'mute', stateKey: 'muted', prevState: status.muted }) }} > {status.muted ? '取消静音' : '静音'} {status.account.id === localAccountId && ( { setModalVisible(false) mutateAction({ id: status.id, type: 'pin', stateKey: 'pinned', prevState: status.pinned }) }} > {status.pinned ? '取消置顶' : '置顶'} )} 静音用户,屏蔽用户,屏蔽域名,举报用户 ) } const styles = StyleSheet.create({ actions: { width: '100%', flex: 1, flexDirection: 'row', marginTop: constants.SPACING_M }, action: { width: '20%', flexDirection: 'row', justifyContent: 'center' }, modalBackground: { width: '100%', height: '100%', backgroundColor: 'rgba(0, 0, 0, 0.75)', flex: 1, flexDirection: 'row', justifyContent: 'center', alignItems: 'flex-end' }, modalSheet: { width: '100%', height: '50%', backgroundColor: 'white', flex: 1 } }) export default ActionsStatus