78 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
import { useRef, useEffect, useCallback } from 'react';
 | 
						|
 | 
						|
import { Helmet } from 'react-helmet';
 | 
						|
import { useParams } from 'react-router-dom';
 | 
						|
 | 
						|
import ExploreIcon from '@/material-icons/400-24px/explore.svg?react';
 | 
						|
import { expandLinkTimeline } from 'flavours/glitch/actions/timelines';
 | 
						|
import Column from 'flavours/glitch/components/column';
 | 
						|
import { ColumnHeader } from 'flavours/glitch/components/column_header';
 | 
						|
import StatusListContainer from 'flavours/glitch/features/ui/containers/status_list_container';
 | 
						|
import type { Card } from 'flavours/glitch/models/status';
 | 
						|
import { useAppDispatch, useAppSelector } from 'flavours/glitch/store';
 | 
						|
 | 
						|
export const LinkTimeline: React.FC<{
 | 
						|
  multiColumn: boolean;
 | 
						|
}> = ({ multiColumn }) => {
 | 
						|
  const { url } = useParams<{ url: string }>();
 | 
						|
  const decodedUrl = url ? decodeURIComponent(url) : undefined;
 | 
						|
  const dispatch = useAppDispatch();
 | 
						|
  const columnRef = useRef<Column>(null);
 | 
						|
  const firstStatusId = useAppSelector((state) =>
 | 
						|
    decodedUrl
 | 
						|
      ? // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
 | 
						|
        (state.timelines.getIn([`link:${decodedUrl}`, 'items', 0]) as string)
 | 
						|
      : undefined,
 | 
						|
  );
 | 
						|
  const story = useAppSelector((state) =>
 | 
						|
    firstStatusId
 | 
						|
      ? (state.statuses.getIn([firstStatusId, 'card']) as Card)
 | 
						|
      : undefined,
 | 
						|
  );
 | 
						|
 | 
						|
  const handleHeaderClick = useCallback(() => {
 | 
						|
    columnRef.current?.scrollTop();
 | 
						|
  }, []);
 | 
						|
 | 
						|
  const handleLoadMore = useCallback(
 | 
						|
    (maxId: string) => {
 | 
						|
      dispatch(expandLinkTimeline(decodedUrl, { maxId }));
 | 
						|
    },
 | 
						|
    [dispatch, decodedUrl],
 | 
						|
  );
 | 
						|
 | 
						|
  useEffect(() => {
 | 
						|
    dispatch(expandLinkTimeline(decodedUrl));
 | 
						|
  }, [dispatch, decodedUrl]);
 | 
						|
 | 
						|
  return (
 | 
						|
    <Column bindToDocument={!multiColumn} ref={columnRef} label={story?.title}>
 | 
						|
      <ColumnHeader
 | 
						|
        icon='explore'
 | 
						|
        iconComponent={ExploreIcon}
 | 
						|
        title={story?.title}
 | 
						|
        onClick={handleHeaderClick}
 | 
						|
        multiColumn={multiColumn}
 | 
						|
        showBackButton
 | 
						|
      />
 | 
						|
 | 
						|
      <StatusListContainer
 | 
						|
        timelineId={`link:${decodedUrl}`}
 | 
						|
        onLoadMore={handleLoadMore}
 | 
						|
        trackScroll
 | 
						|
        scrollKey={`link_timeline-${decodedUrl}`}
 | 
						|
        bindToDocument={!multiColumn}
 | 
						|
        regex={undefined}
 | 
						|
      />
 | 
						|
 | 
						|
      <Helmet>
 | 
						|
        <title>{story?.title}</title>
 | 
						|
        <meta name='robots' content='noindex' />
 | 
						|
      </Helmet>
 | 
						|
    </Column>
 | 
						|
  );
 | 
						|
};
 | 
						|
 | 
						|
// eslint-disable-next-line import/no-default-export
 | 
						|
export default LinkTimeline;
 |