2022-08-30 13:26:42 -07:00
import debounce from 'lodash/debounce' ;
2023-05-30 06:04:50 -07:00
import React , { useCallback , useEffect , useState } from 'react' ;
2022-08-09 12:34:08 -07:00
import { defineMessages , useIntl } from 'react-intl' ;
2023-05-30 06:04:50 -07:00
import { Redirect } from 'react-router-dom' ;
2022-01-10 14:25:06 -08:00
2022-01-10 14:17:52 -08:00
import {
2022-06-07 13:21:18 -07:00
fetchStatusWithContext ,
fetchNext ,
2022-05-30 11:23:55 -07:00
} from 'soapbox/actions/statuses' ;
2022-11-15 08:00:49 -08:00
import MissingIndicator from 'soapbox/components/missing-indicator' ;
2022-07-13 18:13:37 -07:00
import PullToRefresh from 'soapbox/components/pull-to-refresh' ;
2023-05-30 06:04:50 -07:00
import { Column } from 'soapbox/components/ui' ;
2022-11-15 11:00:40 -08:00
import PlaceholderStatus from 'soapbox/features/placeholder/components/placeholder-status' ;
2023-05-30 06:04:50 -07:00
import { useAppDispatch , useAppSelector } from 'soapbox/hooks' ;
2022-05-30 11:23:55 -07:00
import { makeGetStatus } from 'soapbox/selectors' ;
2020-03-27 13:59:38 -07:00
2023-05-30 06:04:50 -07:00
import Thread from './components/thread' ;
2022-04-04 12:17:24 -07:00
2020-03-27 13:59:38 -07:00
const messages = defineMessages ( {
2023-04-05 07:30:05 -07:00
title : { id : 'status.title' , defaultMessage : 'Post Details' } ,
2021-10-14 06:49:33 -07:00
titleDirect : { id : 'status.title_direct' , defaultMessage : 'Direct message' } ,
2020-03-27 13:59:38 -07:00
deleteConfirm : { id : 'confirmations.delete.confirm' , defaultMessage : 'Delete' } ,
2022-01-06 07:51:34 -08:00
deleteHeading : { id : 'confirmations.delete.heading' , defaultMessage : 'Delete post' } ,
2020-03-27 13:59:38 -07:00
deleteMessage : { id : 'confirmations.delete.message' , defaultMessage : 'Are you sure you want to delete this post?' } ,
redraftConfirm : { id : 'confirmations.redraft.confirm' , defaultMessage : 'Delete & redraft' } ,
2021-12-30 08:38:57 -08:00
redraftHeading : { id : 'confirmations.redraft.heading' , defaultMessage : 'Delete & redraft' } ,
2020-03-27 13:59:38 -07:00
redraftMessage : { id : 'confirmations.redraft.message' , defaultMessage : 'Are you sure you want to delete this post and re-draft it? Favorites and reposts will be lost, and replies to the original post will be orphaned.' } ,
blockConfirm : { id : 'confirmations.block.confirm' , defaultMessage : 'Block' } ,
revealAll : { id : 'status.show_more_all' , defaultMessage : 'Show more for all' } ,
hideAll : { id : 'status.show_less_all' , defaultMessage : 'Show less for all' } ,
detailedStatus : { id : 'status.detailed_status' , defaultMessage : 'Detailed conversation view' } ,
replyConfirm : { id : 'confirmations.reply.confirm' , defaultMessage : 'Reply' } ,
replyMessage : { id : 'confirmations.reply.message' , defaultMessage : 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' } ,
blockAndReport : { id : 'confirmations.block.block_and_report' , defaultMessage : 'Block & Report' } ,
} ) ;
2023-03-20 18:57:49 -07:00
type RouteParams = {
statusId : string
groupId? : string
2023-04-17 12:42:08 -07:00
groupSlug? : string
2023-03-20 18:57:49 -07:00
} ;
2022-08-08 17:31:19 -07:00
2023-05-30 06:04:50 -07:00
interface IStatusDetails {
2023-02-15 13:26:27 -08:00
params : RouteParams
2022-08-08 17:31:19 -07:00
}
2023-05-30 06:04:50 -07:00
const StatusDetails : React.FC < IStatusDetails > = ( props ) = > {
2022-08-08 17:31:19 -07:00
const dispatch = useAppDispatch ( ) ;
2023-05-30 06:04:50 -07:00
const intl = useIntl ( ) ;
2022-08-08 17:31:19 -07:00
2022-09-13 01:21:56 -07:00
const getStatus = useCallback ( makeGetStatus ( ) , [ ] ) ;
2023-05-30 06:04:50 -07:00
const status = useAppSelector ( ( state ) = > getStatus ( state , { id : props.params.statusId } ) ) ;
2020-03-27 13:59:38 -07:00
2022-08-08 17:31:19 -07:00
const [ isLoaded , setIsLoaded ] = useState < boolean > ( ! ! status ) ;
const [ next , setNext ] = useState < string > ( ) ;
2020-03-27 13:59:38 -07:00
2022-08-08 17:31:19 -07:00
/** Fetch the status (and context) from the API. */
2022-10-20 07:48:41 -07:00
const fetchData = async ( ) = > {
2022-08-08 17:31:19 -07:00
const { params } = props ;
2021-11-04 11:16:28 -07:00
const { statusId } = params ;
2022-04-23 20:31:49 -07:00
const { next } = await dispatch ( fetchStatusWithContext ( statusId ) ) ;
2022-08-08 17:31:19 -07:00
setNext ( next ) ;
} ;
2021-11-04 10:34:22 -07:00
2022-08-08 17:31:19 -07:00
// Load data.
useEffect ( ( ) = > {
fetchData ( ) . then ( ( ) = > {
setIsLoaded ( true ) ;
2023-05-30 06:04:50 -07:00
} ) . catch ( ( ) = > {
2022-08-08 17:31:19 -07:00
setIsLoaded ( true ) ;
2022-04-04 12:44:31 -07:00
} ) ;
2022-08-08 17:31:19 -07:00
} , [ props . params . statusId ] ) ;
2020-03-27 13:59:38 -07:00
2022-08-08 17:31:19 -07:00
const handleLoadMore = useCallback ( debounce ( ( ) = > {
if ( next && status ) {
dispatch ( fetchNext ( status . id , next ) ) . then ( ( { next } ) = > {
setNext ( next ) ;
2022-11-09 11:03:38 -08:00
} ) . catch ( ( ) = > { } ) ;
2022-04-23 20:31:49 -07:00
}
2022-08-08 17:31:19 -07:00
} , 300 , { leading : true } ) , [ next , status ] ) ;
2022-04-27 13:50:35 -07:00
2023-05-30 06:04:50 -07:00
const handleRefresh = ( ) = > {
return fetchData ( ) ;
2022-08-08 17:31:19 -07:00
} ;
2022-04-27 13:50:35 -07:00
2022-09-20 15:12:52 -07:00
if ( status ? . event ) {
return (
< Redirect to = { ` /@ ${ status . getIn ( [ 'account' , 'acct' ] ) } /events/ ${ status . id } ` } / >
) ;
}
2022-08-08 17:31:19 -07:00
if ( ! status && isLoaded ) {
return (
< MissingIndicator / >
) ;
} else if ( ! status ) {
return (
2023-05-08 08:44:07 -07:00
< Column >
< PlaceholderStatus / >
< / Column >
2022-08-08 17:31:19 -07:00
) ;
}
2020-03-27 13:59:38 -07:00
2023-04-17 12:42:08 -07:00
if ( status . group && typeof status . group === 'object' ) {
if ( status . group . slug && ! props . params . groupSlug ) {
return < Redirect to = { ` /group/ ${ status . group . slug } /posts/ ${ props . params . statusId } ` } / > ;
}
2023-03-20 18:57:49 -07:00
}
2023-04-05 13:21:15 -07:00
const titleMessage = ( ) = > {
if ( status . visibility === 'direct' ) return messages . titleDirect ;
2023-04-12 06:44:29 -07:00
return messages . title ;
2023-04-05 13:21:15 -07:00
} ;
2023-04-05 07:30:05 -07:00
2022-08-08 17:31:19 -07:00
return (
2023-04-05 13:21:15 -07:00
< Column label = { intl . formatMessage ( titleMessage ( ) ) } >
2022-08-08 17:31:19 -07:00
< PullToRefresh onRefresh = { handleRefresh } >
2023-05-30 06:04:50 -07:00
< Thread
status = { status }
next = { next }
handleLoadMore = { handleLoadMore }
/ >
2022-08-08 17:31:19 -07:00
< / PullToRefresh >
< / Column >
) ;
} ;
2022-04-04 12:17:24 -07:00
2023-05-30 06:04:50 -07:00
export default StatusDetails ;